l3lab/ntp-mathlib huggingface dataset:
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₁ s₂ : CompositionSeries X
h : List.ofFn s₁.series = List.ofFn s₂.series
⊢ s₁ = s₂

Next tactic:
have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₁ s₂ : CompositionSeries X
h : List.ofFn s₁.series = List.ofFn s₂.series
h₁ : s₁.length = s₂.length
⊢ s₁ = s₂

Next tactic:
have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₁ s₂ : CompositionSeries X
h : List.ofFn s₁.series = List.ofFn s₂.series
h₁ : s₁.length = s₂.length
h₂ :
  ∀ (i : Fin (Nat.succ s₁.length)), series s₁ i = series s₂ (Fin.cast (_ : Nat.succ s₁.length = Nat.succ s₂.length) i)
⊢ s₁ = s₂

Next tactic:
cases s₁
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  

Proof state:
case mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₂ : CompositionSeries X
length✝ : ℕ
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h : List.ofFn { length := length✝, series := series✝, step' := step'✝ }.series = List.ofFn s₂.series
h₁ : { length := length✝, series := series✝, step' := step'✝ }.length = s₂.length
h₂ :
  ∀ (i : Fin (Nat.succ { length := length✝, series := series✝, step' := step'✝ }.length)),
    series { length := length✝, series := series✝, step' := step'✝ } i =
      series s₂
        (Fin.cast (_ : Nat.succ { length := length✝, series := series✝, step' := step'✝ }.length = Nat.succ s₂.length)
          i)
⊢ { length := length✝, series := series✝, step' := step'✝ } = s₂

Next tactic:
cases s₂
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  cases s₂
  -- Porting note: `dsimp at *` doesn't work. Why?
  

Proof state:
case mk.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
length✝¹ : ℕ
series✝¹ : Fin (length✝¹ + 1) → X
step'✝¹ : ∀ (i : Fin length✝¹), IsMaximal (series✝¹ (Fin.castSucc i)) (series✝¹ (Fin.succ i))
length✝ : ℕ
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h :
  List.ofFn { length := length✝¹, series := series✝¹, step' := step'✝¹ }.series =
    List.ofFn { length := length✝, series := series✝, step' := step'✝ }.series
h₁ :
  { length := length✝¹, series := series✝¹, step' := step'✝¹ }.length =
    { length := length✝, series := series✝, step' := step'✝ }.length
h₂ :
  ∀ (i : Fin (Nat.succ { length := length✝¹, series := series✝¹, step' := step'✝¹ }.length)),
    series { length := length✝¹, series := series✝¹, step' := step'✝¹ } i =
      series { length := length✝, series := series✝, step' := step'✝ }
        (Fin.cast
          (_ :
            Nat.succ { length := length✝¹, series := series✝¹, step' := step'✝¹ }.length =
              Nat.succ { length := length✝, series := series✝, step' := step'✝ }.length)
          i)
⊢ { length := length✝¹, series := series✝¹, step' := step'✝¹ } =
    { length := length✝, series := series✝, step' := step'✝ }

Next tactic:
dsimp at h h₁ h₂
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  cases s₂
  -- Porting note: `dsimp at *` doesn't work. Why?
  dsimp at h h₁ h₂
  

Proof state:
case mk.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
length✝¹ : ℕ
series✝¹ : Fin (length✝¹ + 1) → X
step'✝¹ : ∀ (i : Fin length✝¹), IsMaximal (series✝¹ (Fin.castSucc i)) (series✝¹ (Fin.succ i))
length✝ : ℕ
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h : List.ofFn series✝¹ = List.ofFn series✝
h₁ : length✝¹ = length✝
h₂ : ∀ (i : Fin (Nat.succ length✝¹)), series✝¹ i = series✝ (Fin.cast (_ : Nat.succ length✝¹ = Nat.succ length✝) i)
⊢ { length := length✝¹, series := series✝¹, step' := step'✝¹ } =
    { length := length✝, series := series✝, step' := step'✝ }

Next tactic:
subst h₁
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  cases s₂
  -- Porting note: `dsimp at *` doesn't work. Why?
  dsimp at h h₁ h₂
  subst h₁
  -- Porting note: `[heq_iff_eq, eq_self_iff_true, true_and_iff]`
  --             → `[mk.injEq, heq_eq_eq, true_and]`
  

Proof state:
case mk.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
length✝ : ℕ
series✝¹ : Fin (length✝ + 1) → X
step'✝¹ : ∀ (i : Fin length✝), IsMaximal (series✝¹ (Fin.castSucc i)) (series✝¹ (Fin.succ i))
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h : List.ofFn series✝¹ = List.ofFn series✝
h₂ : ∀ (i : Fin (Nat.succ length✝)), series✝¹ i = series✝ (Fin.cast (_ : Nat.succ length✝ = Nat.succ length✝) i)
⊢ { length := length✝, series := series✝¹, step' := step'✝¹ } =
    { length := length✝, series := series✝, step' := step'✝ }

Next tactic:
simp only [mk.injEq, heq_eq_eq, true_and]
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  cases s₂
  -- Porting note: `dsimp at *` doesn't work. Why?
  dsimp at h h₁ h₂
  subst h₁
  -- Porting note: `[heq_iff_eq, eq_self_iff_true, true_and_iff]`
  --             → `[mk.injEq, heq_eq_eq, true_and]`
  simp only [mk.injEq, heq_eq_eq, true_and]
  

Proof state:
case mk.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
length✝ : ℕ
series✝¹ : Fin (length✝ + 1) → X
step'✝¹ : ∀ (i : Fin length✝), IsMaximal (series✝¹ (Fin.castSucc i)) (series✝¹ (Fin.succ i))
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h : List.ofFn series✝¹ = List.ofFn series✝
h₂ : ∀ (i : Fin (Nat.succ length✝)), series✝¹ i = series✝ (Fin.cast (_ : Nat.succ length✝ = Nat.succ length✝) i)
⊢ series✝¹ = series✝

Next tactic:
simp only [Fin.cast_refl] at h₂
theorem toList_injective : Function.Injective (@CompositionSeries.toList X _ _) :=
  fun s₁ s₂ (h : List.ofFn s₁ = List.ofFn s₂) => by
  have h₁ : s₁.length = s₂.length :=
    Nat.succ_injective
      ((List.length_ofFn s₁).symm.trans <| (congr_arg List.length h).trans <| List.length_ofFn s₂)
  have h₂ : ∀ i : Fin s₁.length.succ, s₁ i = s₂ (Fin.cast (congr_arg Nat.succ h₁) i) :=
    -- Porting note: `List.nthLe_ofFn` has been deprecated but `List.get_ofFn` has a
    --               different type, so we do golf here.
    congr_fun <| List.ofFn_injective <| h.trans <| List.ofFn_congr (congr_arg Nat.succ h₁).symm _
  cases s₁
  cases s₂
  -- Porting note: `dsimp at *` doesn't work. Why?
  dsimp at h h₁ h₂
  subst h₁
  -- Porting note: `[heq_iff_eq, eq_self_iff_true, true_and_iff]`
  --             → `[mk.injEq, heq_eq_eq, true_and]`
  simp only [mk.injEq, heq_eq_eq, true_and]
  simp only [Fin.cast_refl] at h₂
  

Proof state:
case mk.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
length✝ : ℕ
series✝¹ : Fin (length✝ + 1) → X
step'✝¹ : ∀ (i : Fin length✝), IsMaximal (series✝¹ (Fin.castSucc i)) (series✝¹ (Fin.succ i))
series✝ : Fin (length✝ + 1) → X
step'✝ : ∀ (i : Fin length✝), IsMaximal (series✝ (Fin.castSucc i)) (series✝ (Fin.succ i))
h : List.ofFn series✝¹ = List.ofFn series✝
h₂ : ∀ (i : Fin (Nat.succ length✝)), series✝¹ i = series✝ (id i)
⊢ series✝¹ = series✝

Next tactic:
exact funext h₂
theorem chain'_toList (s : CompositionSeries X) : List.Chain' IsMaximal s.toList :=
  List.chain'_iff_get.2
    (by
      

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
⊢ ∀ (i : ℕ) (h : i < List.length (toList s) - 1),
    IsMaximal (List.get (toList s) { val := i, isLt := (_ : i < List.length (toList s)) })
      (List.get (toList s) { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList s)) })

Next tactic:
intro i hi
theorem chain'_toList (s : CompositionSeries X) : List.Chain' IsMaximal s.toList :=
  List.chain'_iff_get.2
    (by
      intro i hi
      

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i : ℕ
hi : i < List.length (toList s) - 1
⊢ IsMaximal (List.get (toList s) { val := i, isLt := (_ : i < List.length (toList s)) })
    (List.get (toList s) { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList s)) })

Next tactic:
simp only [toList, List.get_ofFn]
theorem chain'_toList (s : CompositionSeries X) : List.Chain' IsMaximal s.toList :=
  List.chain'_iff_get.2
    (by
      intro i hi
      simp only [toList, List.get_ofFn]
      

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i : ℕ
hi : i < List.length (toList s) - 1
⊢ IsMaximal
    (series s
      (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1)
        { val := i, isLt := (_ : i < List.length (toList s)) }))
    (series s
      (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1)
        { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList s)) }))

Next tactic:
rw [length_toList] at hi
theorem chain'_toList (s : CompositionSeries X) : List.Chain' IsMaximal s.toList :=
  List.chain'_iff_get.2
    (by
      intro i hi
      simp only [toList, List.get_ofFn]
      rw [length_toList] at hi
      

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i : ℕ
hi✝ : i < List.length (toList s) - 1
hi : i < s.length + 1 - 1
⊢ IsMaximal
    (series s
      (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1)
        { val := i, isLt := (_ : i < List.length (toList s)) }))
    (series s
      (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1)
        { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList s)) }))

Next tactic:
exact s.step ⟨i, hi⟩
theorem toList_sorted (s : CompositionSeries X) : s.toList.Sorted (· < ·) :=
  List.pairwise_iff_get.2 fun i j h => by
    

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i j : Fin (List.length (toList s))
h : i < j
⊢ List.get (toList s) i < List.get (toList s) j

Next tactic:
dsimp [toList]
theorem toList_sorted (s : CompositionSeries X) : s.toList.Sorted (· < ·) :=
  List.pairwise_iff_get.2 fun i j h => by
    dsimp [toList]
    

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i j : Fin (List.length (toList s))
h : i < j
⊢ List.get (List.ofFn s.series) i < List.get (List.ofFn s.series) j

Next tactic:
rw [List.get_ofFn, List.get_ofFn]
theorem toList_sorted (s : CompositionSeries X) : s.toList.Sorted (· < ·) :=
  List.pairwise_iff_get.2 fun i j h => by
    dsimp [toList]
    rw [List.get_ofFn, List.get_ofFn]
    

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i j : Fin (List.length (toList s))
h : i < j
⊢ series s (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1) i) <
    series s (Fin.cast (_ : List.length (List.ofFn s.series) = s.length + 1) j)

Next tactic:
exact s.strictMono h
@[simp]
theorem mem_toList {s : CompositionSeries X} {x : X} : x ∈ s.toList ↔ x ∈ s := by
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
x : X
⊢ x ∈ toList s ↔ x ∈ s

Next tactic:
rw [toList, List.mem_ofFn, mem_def]
/-- Make a `CompositionSeries X` from the ordered list of its elements. -/
def ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) : CompositionSeries X
    where
  length := l.length - 1
  series i :=
    l.nthLe i
      (by
        

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : Fin (List.length l - 1 + 1)
⊢ ↑i < List.length l

Next tactic:
conv_rhs => rw [← tsub_add_cancel_of_le (Nat.succ_le_of_lt (List.length_pos_of_ne_nil hl))]
/-- Make a `CompositionSeries X` from the ordered list of its elements. -/
def ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) : CompositionSeries X
    where
  length := l.length - 1
  series i :=
    l.nthLe i
      (by
        conv_rhs => 

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : Fin (List.length l - 1 + 1)
| List.length l

Next tactic:
rw [← tsub_add_cancel_of_le (Nat.succ_le_of_lt (List.length_pos_of_ne_nil hl))]
/-- Make a `CompositionSeries X` from the ordered list of its elements. -/
def ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) : CompositionSeries X
    where
  length := l.length - 1
  series i :=
    l.nthLe i
      (by
        conv_rhs => rw [← tsub_add_cancel_of_le (Nat.succ_le_of_lt (List.length_pos_of_ne_nil hl))]
        

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : Fin (List.length l - 1 + 1)
⊢ ↑i < List.length l - Nat.succ 0 + Nat.succ 0

Next tactic:
exact i.2
theorem ofList_toList (s : CompositionSeries X) :
    ofList s.toList s.toList_ne_nil s.chain'_toList = s := by
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
⊢ ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s)) = s

Next tactic:
refine' ext_fun _ _
theorem ofList_toList (s : CompositionSeries X) :
    ofList s.toList s.toList_ne_nil s.chain'_toList = s := by
  refine' ext_fun _ _
  · 

Proof state:
case refine'_1
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
⊢ (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))).length = s.length

Next tactic:
rw [length_ofList, length_toList, Nat.add_one_sub_one]
theorem ofList_toList (s : CompositionSeries X) :
    ofList s.toList s.toList_ne_nil s.chain'_toList = s := by
  refine' ext_fun _ _
  · rw [length_ofList, length_toList, Nat.add_one_sub_one]
  · 

Proof state:
case refine'_2
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
⊢ ∀ (i : Fin ((ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))).length + 1)),
    series (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))) i =
      series s
        (Fin.cast
          (_ :
            Nat.succ (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))).length =
              Nat.succ s.length)
          i)

Next tactic:
rintro ⟨i, hi⟩
theorem ofList_toList (s : CompositionSeries X) :
    ofList s.toList s.toList_ne_nil s.chain'_toList = s := by
  refine' ext_fun _ _
  · rw [length_ofList, length_toList, Nat.add_one_sub_one]
  · rintro ⟨i, hi⟩
    -- Porting note: Was `dsimp [ofList, toList]; rw [List.nthLe_ofFn']`.
    

Proof state:
case refine'_2.mk
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s : CompositionSeries X
i : ℕ
hi : i < (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))).length + 1
⊢ series (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))) { val := i, isLt := hi } =
    series s
      (Fin.cast
        (_ :
          Nat.succ (ofList (toList s) (_ : toList s ≠ []) (_ : List.Chain' IsMaximal (toList s))).length =
            Nat.succ s.length)
        { val := i, isLt := hi })

Next tactic:
simp [ofList, toList, -List.ofFn_succ]
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
⊢ toList (ofList l hl hc) = l

Next tactic:
refine' List.ext_get _ _
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  refine' List.ext_get _ _
  · 

Proof state:
case refine'_1
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
⊢ List.length (toList (ofList l hl hc)) = List.length l

Next tactic:
rw [length_toList, length_ofList,
      tsub_add_cancel_of_le (Nat.succ_le_of_lt <| List.length_pos_of_ne_nil hl)]
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  refine' List.ext_get _ _
  · rw [length_toList, length_ofList,
      tsub_add_cancel_of_le (Nat.succ_le_of_lt <| List.length_pos_of_ne_nil hl)]
  · 

Proof state:
case refine'_2
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
⊢ ∀ (n : ℕ) (h₁ : n < List.length (toList (ofList l hl hc))) (h₂ : n < List.length l),
    List.get (toList (ofList l hl hc)) { val := n, isLt := h₁ } = List.get l { val := n, isLt := h₂ }

Next tactic:
intro i hi hi'
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  refine' List.ext_get _ _
  · rw [length_toList, length_ofList,
      tsub_add_cancel_of_le (Nat.succ_le_of_lt <| List.length_pos_of_ne_nil hl)]
  · intro i hi hi'
    

Proof state:
case refine'_2
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : ℕ
hi : i < List.length (toList (ofList l hl hc))
hi' : i < List.length l
⊢ List.get (toList (ofList l hl hc)) { val := i, isLt := hi } = List.get l { val := i, isLt := hi' }

Next tactic:
dsimp [ofList, toList]
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  refine' List.ext_get _ _
  · rw [length_toList, length_ofList,
      tsub_add_cancel_of_le (Nat.succ_le_of_lt <| List.length_pos_of_ne_nil hl)]
  · intro i hi hi'
    dsimp [ofList, toList]
    

Proof state:
case refine'_2
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : ℕ
hi : i < List.length (toList (ofList l hl hc))
hi' : i < List.length l
⊢ List.get (List.ofFn fun i => List.nthLe l ↑i (_ : ↑i < List.length l)) { val := i, isLt := hi } =
    List.get l { val := i, isLt := hi' }

Next tactic:
rw [List.get_ofFn]
@[simp]
theorem toList_ofList (l : List X) (hl : l ≠ []) (hc : List.Chain' IsMaximal l) :
    toList (ofList l hl hc) = l := by
  refine' List.ext_get _ _
  · rw [length_toList, length_ofList,
      tsub_add_cancel_of_le (Nat.succ_le_of_lt <| List.length_pos_of_ne_nil hl)]
  · intro i hi hi'
    dsimp [ofList, toList]
    rw [List.get_ofFn]
    

Proof state:
case refine'_2
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
l : List X
hl : l ≠ []
hc : List.Chain' IsMaximal l
i : ℕ
hi : i < List.length (toList (ofList l hl hc))
hi' : i < List.length l
⊢ List.nthLe l
      ↑(Fin.cast (_ : List.length (List.ofFn fun i => List.nthLe l ↑i (_ : ↑i < List.length l)) = List.length l - 1 + 1)
          { val := i, isLt := hi })
      (_ :
        ↑(Fin.cast
              (_ : List.length (List.ofFn fun i => List.nthLe l ↑i (_ : ↑i < List.length l)) = List.length l - 1 + 1)
              { val := i, isLt := hi }) <
          List.length l) =
    List.get l { val := i, isLt := hi' }

Next tactic:
rfl
/-- Two `CompositionSeries` are equal if they have the same elements. See also `ext_fun`. -/
@[ext]
theorem ext {s₁ s₂ : CompositionSeries X} (h : ∀ x, x ∈ s₁ ↔ x ∈ s₂) : s₁ = s₂ :=
  toList_injective <|
    List.eq_of_perm_of_sorted
      (by
        

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₁ s₂ : CompositionSeries X
h : ∀ (x : X), x ∈ s₁ ↔ x ∈ s₂
⊢ List.Perm (toList s₁) (toList s₂)

Next tactic:
classical
        exact List.perm_of_nodup_nodup_toFinset_eq s₁.toList_nodup s₂.toList_nodup
          (Finset.ext <| by simp [*])
/-- Two `CompositionSeries` are equal if they have the same elements. See also `ext_fun`. -/
@[ext]
theorem ext {s₁ s₂ : CompositionSeries X} (h : ∀ x, x ∈ s₁ ↔ x ∈ s₂) : s₁ = s₂ :=
  toList_injective <|
    List.eq_of_perm_of_sorted
      (by
        classical
        

Proof state:
X : Type u
inst✝¹ : Lattice X
inst✝ : JordanHolderLattice X
s₁ s₂ : CompositionSeries X
h : ∀ (x : X), x ∈ s₁ ↔ x ∈ s₂
⊢ List.Perm (toList s₁) (toList s₂)

Next tactic:
exact List.perm_of_nodup_nodup_toFinset_eq s₁.toList_nodup s₂.toList_nodup
          (Finset.ext <| by simp [*])