l3lab/ntp-mathlib huggingface dataset:
theorem sum_to_range :
    Set.range (sum_to C ho) = GoodProducts (π C (ord I · < o)) ∪ MaxProducts C ho := by
  have h : Set.range (sum_to C ho) = _ ∪ _ := Set.Sum.elim_range _ _; rw [h]; congr<;> ext l
  · exact ⟨fun ⟨m,hm⟩ ↦ by rw [← hm]; exact m.prop, fun hl ↦ ⟨⟨l,hl⟩, rfl⟩⟩
  · 

Proof state:
case e_a.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h : Set.range (sum_to C ho) = Set.range Subtype.val ∪ Set.range Subtype.val
l : Products I
⊢ l ∈ Set.range Subtype.val ↔ l ∈ MaxProducts C ho

Next tactic:
exact ⟨fun ⟨m,hm⟩ ↦ by rw [← hm]; exact m.prop, fun hl ↦ ⟨⟨l,hl⟩, rfl⟩⟩
theorem sum_to_range :
    Set.range (sum_to C ho) = GoodProducts (π C (ord I · < o)) ∪ MaxProducts C ho := by
  have h : Set.range (sum_to C ho) = _ ∪ _ := Set.Sum.elim_range _ _; rw [h]; congr<;> ext l
  · exact ⟨fun ⟨m,hm⟩ ↦ by rw [← hm]; exact m.prop, fun hl ↦ ⟨⟨l,hl⟩, rfl⟩⟩
  · exact ⟨fun ⟨m,hm⟩ ↦ by 

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h : Set.range (sum_to C ho) = Set.range Subtype.val ∪ Set.range Subtype.val
l : Products I
x✝ : l ∈ Set.range Subtype.val
m : ↑(MaxProducts C ho)
hm : ↑m = l
⊢ l ∈ MaxProducts C ho

Next tactic:
rw [← hm]
theorem sum_to_range :
    Set.range (sum_to C ho) = GoodProducts (π C (ord I · < o)) ∪ MaxProducts C ho := by
  have h : Set.range (sum_to C ho) = _ ∪ _ := Set.Sum.elim_range _ _; rw [h]; congr<;> ext l
  · exact ⟨fun ⟨m,hm⟩ ↦ by rw [← hm]; exact m.prop, fun hl ↦ ⟨⟨l,hl⟩, rfl⟩⟩
  · exact ⟨fun ⟨m,hm⟩ ↦ by rw [← hm]; 

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
h : Set.range (sum_to C ho) = Set.range Subtype.val ∪ Set.range Subtype.val
l : Products I
x✝ : l ∈ Set.range Subtype.val
m : ↑(MaxProducts C ho)
hm : ↑m = l
⊢ ↑m ∈ MaxProducts C ho

Next tactic:
exact m.prop
/-- The equivalence from the sum of `GoodProducts (π C (ord I · < o))` and
    `(MaxProducts C ho)` to `GoodProducts C`. -/
noncomputable
def sum_equiv : GoodProducts (π C (ord I · < o)) ⊕ (MaxProducts C ho) ≃ GoodProducts C :=
  calc _ ≃ Set.range (sum_to C ho) := Equiv.ofInjective (sum_to C ho) (injective_sum_to C ho)
       _ ≃ _ := Equiv.Set.ofEq <| by 

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ Set.range (sum_to C ho) = GoodProducts C

Next tactic:
rw [sum_to_range C ho, union_succ C hsC ho]
theorem sum_equiv_comp_eval_eq_elim : eval C ∘ (sum_equiv C hsC ho).toFun =
    (Sum.elim (fun (l : GoodProducts (π C (ord I · < o))) ↦ Products.eval C l.1)
    (fun (l : MaxProducts C ho) ↦ Products.eval C l.1)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ eval C ∘ (sum_equiv C hsC ho).toFun = Sum.elim (fun l => Products.eval C ↑l) fun l => Products.eval C ↑l

Next tactic:
ext ⟨_,_⟩ <;> [rfl; rfl]
theorem sum_equiv_comp_eval_eq_elim : eval C ∘ (sum_equiv C hsC ho).toFun =
    (Sum.elim (fun (l : GoodProducts (π C (ord I · < o))) ↦ Products.eval C l.1)
    (fun (l : MaxProducts C ho) ↦ Products.eval C l.1)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ eval C ∘ (sum_equiv C hsC ho).toFun = Sum.elim (fun l => Products.eval C ↑l) fun l => Products.eval C ↑l

Next tactic:
ext ⟨_,_⟩
theorem sum_equiv_comp_eval_eq_elim : eval C ∘ (sum_equiv C hsC ho).toFun =
    (Sum.elim (fun (l : GoodProducts (π C (ord I · < o))) ↦ Products.eval C l.1)
    (fun (l : MaxProducts C ho) ↦ Products.eval C l.1)) := by
  ext ⟨_,_⟩ <;> [

Proof state:
case h.inl.mk.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
val✝ : Products I
property✝ : val✝ ∈ GoodProducts (π C fun x => ord I x < o)
x✝ : ↑C
⊢ ((eval C ∘ (sum_equiv C hsC ho).toFun) (Sum.inl { val := val✝, property := property✝ })) x✝ =
    (Sum.elim (fun l => Products.eval C ↑l) (fun l => Products.eval C ↑l)
        (Sum.inl { val := val✝, property := property✝ }))
      x✝

Next tactic:
rfl
theorem sum_equiv_comp_eval_eq_elim : eval C ∘ (sum_equiv C hsC ho).toFun =
    (Sum.elim (fun (l : GoodProducts (π C (ord I · < o))) ↦ Products.eval C l.1)
    (fun (l : MaxProducts C ho) ↦ Products.eval C l.1)) := by
  ext ⟨_,_⟩ <;> [rfl; 

Proof state:
case h.inr.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
val✝ : ↑(MaxProducts C ho)
x✝ : ↑C
⊢ ((eval C ∘ (sum_equiv C hsC ho).toFun) (Sum.inr val✝)) x✝ =
    (Sum.elim (fun l => Products.eval C ↑l) (fun l => Products.eval C ↑l) (Sum.inr val✝)) x✝

Next tactic:
rfl
theorem linearIndependent_iff_sum :
    LinearIndependent ℤ (eval C) ↔ LinearIndependent ℤ (SumEval C ho) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent ℤ (eval C) ↔ LinearIndependent ℤ (SumEval C ho)

Next tactic:
rw [← linearIndependent_equiv (sum_equiv C hsC ho), SumEval,
    ← sum_equiv_comp_eval_eq_elim C hsC ho]
theorem linearIndependent_iff_sum :
    LinearIndependent ℤ (eval C) ↔ LinearIndependent ℤ (SumEval C ho) := by
  rw [← linearIndependent_equiv (sum_equiv C hsC ho), SumEval,
    ← sum_equiv_comp_eval_eq_elim C hsC ho]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ LinearIndependent ℤ (eval C ∘ ⇑(sum_equiv C hsC ho)) ↔ LinearIndependent ℤ (eval C ∘ (sum_equiv C hsC ho).toFun)

Next tactic:
exact Iff.rfl
theorem span_sum : Set.range (eval C) = Set.range (Sum.elim
    (fun (l : GoodProducts (π C (ord I · < o))) ↦ Products.eval C l.1)
    (fun (l : MaxProducts C ho) ↦ Products.eval C l.1)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ Set.range (eval C) = Set.range (Sum.elim (fun l => Products.eval C ↑l) fun l => Products.eval C ↑l)

Next tactic:
rw [← sum_equiv_comp_eval_eq_elim C hsC ho, Equiv.toFun_as_coe,
    EquivLike.range_comp (e := sum_equiv C hsC ho)]
theorem square_commutes : SumEval C ho ∘ Sum.inl =
    ModuleCat.ofHom (πs C o) ∘ eval (π C (ord I · < o)) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ SumEval C ho ∘ Sum.inl = ⇑(ModuleCat.ofHom (πs C o)) ∘ eval (π C fun x => ord I x < o)

Next tactic:
ext l
theorem square_commutes : SumEval C ho ∘ Sum.inl =
    ModuleCat.ofHom (πs C o) ∘ eval (π C (ord I · < o)) := by
  ext l
  

Proof state:
case h.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(GoodProducts (π C fun x => ord I x < o))
x✝ : ↑C
⊢ ((SumEval C ho ∘ Sum.inl) l) x✝ = ((⇑(ModuleCat.ofHom (πs C o)) ∘ eval (π C fun x => ord I x < o)) l) x✝

Next tactic:
dsimp [SumEval]
theorem square_commutes : SumEval C ho ∘ Sum.inl =
    ModuleCat.ofHom (πs C o) ∘ eval (π C (ord I · < o)) := by
  ext l
  dsimp [SumEval]
  

Proof state:
case h.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(GoodProducts (π C fun x => ord I x < o))
x✝ : ↑C
⊢ (Products.eval C ↑l) x✝ = ((ModuleCat.ofHom (πs C o)) (eval (π C fun x => ord I x < o) l)) x✝

Next tactic:
rw [← Products.eval_πs C (Products.prop_of_isGood  _ _ l.prop)]
theorem square_commutes : SumEval C ho ∘ Sum.inl =
    ModuleCat.ofHom (πs C o) ∘ eval (π C (ord I · < o)) := by
  ext l
  dsimp [SumEval]
  rw [← Products.eval_πs C (Products.prop_of_isGood  _ _ l.prop)]
  

Proof state:
case h.h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(GoodProducts (π C fun x => ord I x < o))
x✝ : ↑C
⊢ ((πs C o) (Products.eval (π C fun x => ord I x < o) ↑l)) x✝ =
    ((ModuleCat.ofHom (πs C o)) (eval (π C fun x => ord I x < o) l)) x✝

Next tactic:
rfl
theorem swapTrue_eq_true (x : I → Bool) : SwapTrue o x (term I ho) = true := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
x : I → Bool
⊢ SwapTrue o x (term I ho) = true

Next tactic:
simp only [SwapTrue, ord_term_aux, ite_true]
theorem mem_C'_eq_false : ∀ x, x ∈ C' C ho → x (term I ho) = false := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
⊢ ∀ x ∈ C' C ho, x (term I ho) = false

Next tactic:
rintro x ⟨_, y, _, rfl⟩
theorem mem_C'_eq_false : ∀ x, x ∈ C' C ho → x (term I ho) = false := by
  rintro x ⟨_, y, _, rfl⟩
  

Proof state:
case intro.intro.intro
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
y : I → Bool
left✝¹ : y ∈ C1 C ho
left✝ : Proj (fun x => ord I x < o) y ∈ C0 C ho
⊢ Proj (fun x => ord I x < o) y (term I ho) = false

Next tactic:
simp only [Proj, ord_term_aux, lt_self_iff_false, ite_false]
theorem Products.max_eq_o_cons_tail (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) : l.val = term I ho :: l.Tail.val := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
⊢ ↑l = term I ho :: ↑(Tail l)

Next tactic:
rw [← List.cons_head!_tail hl, hlh]
theorem Products.max_eq_o_cons_tail (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) : l.val = term I ho :: l.Tail.val := by
  rw [← List.cons_head!_tail hl, hlh]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
⊢ term I ho :: List.tail ↑l = term I ho :: ↑(Tail l)

Next tactic:
rfl
theorem Products.max_eq_o_cons_tail' (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) (hlc : List.Chain' (·>·) (term I ho :: l.Tail.val)) :
    l = ⟨term I ho :: l.Tail.val, hlc⟩ := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
hlc : List.Chain' (fun x x_1 => x > x_1) (term I ho :: ↑(Tail l))
⊢ l = { val := term I ho :: ↑(Tail l), property := hlc }

Next tactic:
simp_rw [← max_eq_o_cons_tail ho l hl hlh]
theorem Products.max_eq_o_cons_tail' (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) (hlc : List.Chain' (·>·) (term I ho :: l.Tail.val)) :
    l = ⟨term I ho :: l.Tail.val, hlc⟩ := by
  simp_rw [← max_eq_o_cons_tail ho l hl hlh]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
hlc : List.Chain' (fun x x_1 => x > x_1) (term I ho :: ↑(Tail l))
⊢ l = { val := ↑l, property := (_ : (fun l => List.Chain' (fun x x_1 => x > x_1) l) ↑l) }

Next tactic:
rfl
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
⊢ List.head! ↑↑l = term I ho

Next tactic:
rw [eq_comm, ← ord_term ho]
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
⊢ ord I (List.head! ↑↑l) = o

Next tactic:
have hm := l.prop.2
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
⊢ ord I (List.head! ↑↑l) = o

Next tactic:
have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) < Order.succ o
⊢ ord I (List.head! ↑↑l) = o

Next tactic:
simp only [Order.lt_succ_iff] at this
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  simp only [Order.lt_succ_iff] at this
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) ≤ o
⊢ ord I (List.head! ↑↑l) = o

Next tactic:
refine eq_of_le_of_not_lt this (not_lt.mpr ?_)
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  simp only [Order.lt_succ_iff] at this
  refine eq_of_le_of_not_lt this (not_lt.mpr ?_)
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) ≤ o
⊢ o ≤ ord I (List.head! ↑↑l)

Next tactic:
have h : ord I (term I ho) ≤ ord I l.val.val.head!
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  simp only [Order.lt_succ_iff] at this
  refine eq_of_le_of_not_lt this (not_lt.mpr ?_)
  have h : ord I (term I ho) ≤ ord I l.val.val.head!
  · 

Proof state:
case h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) ≤ o
⊢ ord I (term I ho) ≤ ord I (List.head! ↑↑l)

Next tactic:
simp only [← ord_term_aux, ord, Ordinal.typein_le_typein, not_lt]
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  simp only [Order.lt_succ_iff] at this
  refine eq_of_le_of_not_lt this (not_lt.mpr ?_)
  have h : ord I (term I ho) ≤ ord I l.val.val.head!
  · simp only [← ord_term_aux, ord, Ordinal.typein_le_typein, not_lt]
    

Proof state:
case h
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) ≤ o
⊢ term I ho ≤ List.head! ↑↑l

Next tactic:
exact Products.rel_head!_of_mem hm
theorem GoodProducts.head!_eq_o_of_maxProducts (l : ↑(MaxProducts C ho)) :
    l.val.val.head! = term I ho := by
  rw [eq_comm, ← ord_term ho]
  have hm := l.prop.2
  have := Products.prop_of_isGood_of_contained C _ l.prop.1 hsC l.val.val.head!
    (List.head!_mem_self (List.ne_nil_of_mem hm))
  simp only [Order.lt_succ_iff] at this
  refine eq_of_le_of_not_lt this (not_lt.mpr ?_)
  have h : ord I (term I ho) ≤ ord I l.val.val.head!
  · simp only [← ord_term_aux, ord, Ordinal.typein_le_typein, not_lt]
    exact Products.rel_head!_of_mem hm
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : ↑(MaxProducts C ho)
hm : term I ho ∈ ↑↑l
this : ord I (List.head! ↑↑l) ≤ o
h : ord I (term I ho) ≤ ord I (List.head! ↑↑l)
⊢ o ≤ ord I (List.head! ↑↑l)

Next tactic:
rwa [ord_term_aux] at h
theorem Products.evalCons {l : List I} {a : I}
    (hla : (a::l).Chain' (·>·)) : Products.eval C ⟨a::l,hla⟩ =
    (e C a) * Products.eval C ⟨l,List.Chain'.sublist hla (List.tail_sublist (a::l))⟩ := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : List I
a : I
hla : List.Chain' (fun x x_1 => x > x_1) (a :: l)
⊢ eval C { val := a :: l, property := hla } =
    e C a * eval C { val := l, property := (_ : List.Chain' (fun x x_1 => x > x_1) l) }

Next tactic:
simp only [eval._eq_1, List.map, List.prod_cons]
theorem Products.max_eq_eval (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) :
    Linear_CC' C hsC ho (l.eval C) = l.Tail.eval (C' C ho) := by
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
⊢ (Linear_CC' C hsC ho) (eval C l) = eval (C' C ho) (Tail l)

Next tactic:
have hlc : ((term I ho) :: l.Tail.val).Chain' (·>·)
theorem Products.max_eq_eval (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) :
    Linear_CC' C hsC ho (l.eval C) = l.Tail.eval (C' C ho) := by
  have hlc : ((term I ho) :: l.Tail.val).Chain' (·>·)
  · 

Proof state:
case hlc
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
⊢ List.Chain' (fun x x_1 => x > x_1) (term I ho :: ↑(Tail l))

Next tactic:
rw [← max_eq_o_cons_tail ho l hl hlh]
theorem Products.max_eq_eval (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) :
    Linear_CC' C hsC ho (l.eval C) = l.Tail.eval (C' C ho) := by
  have hlc : ((term I ho) :: l.Tail.val).Chain' (·>·)
  · rw [← max_eq_o_cons_tail ho l hl hlh]; 

Proof state:
case hlc
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
⊢ List.Chain' (fun x x_1 => x > x_1) ↑l

Next tactic:
exact l.prop
theorem Products.max_eq_eval (l : Products I) (hl : l.val ≠ [])
    (hlh : l.val.head! = term I ho) :
    Linear_CC' C hsC ho (l.eval C) = l.Tail.eval (C' C ho) := by
  have hlc : ((term I ho) :: l.Tail.val).Chain' (·>·)
  · rw [← max_eq_o_cons_tail ho l hl hlh]; exact l.prop
  

Proof state:
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o : Ordinal.{u}
hC : IsClosed C
hsC : contained C (Order.succ o)
ho : o < Ordinal.type fun x x_1 => x < x_1
l : Products I
hl : ↑l ≠ []
hlh : List.head! ↑l = term I ho
hlc : List.Chain' (fun x x_1 => x > x_1) (term I ho :: ↑(Tail l))
⊢ (Linear_CC' C hsC ho) (eval C l) = eval (C' C ho) (Tail l)

Next tactic:
rw [max_eq_o_cons_tail' ho l hl hlh hlc, Products.evalCons]