l3lab/ntp-mathlib huggingface dataset:
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < 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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
⊢ eval C '' {m | m < l} = ⇑(πs C o) '' (eval (π C fun x => ord I x < o) '' {m | m < l})

Next tactic:
ext f
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  

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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
⊢ f ∈ eval C '' {m | m < l} ↔ f ∈ ⇑(πs C o) '' (eval (π C fun x => ord I x < o) '' {m | m < l})

Next tactic:
simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  

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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
⊢ (∃ x < l, eval C x = f) ↔ ∃ a < l, (πs C o) (eval (π C fun x => ord I x < o) a) = f

Next tactic:
apply exists_congr
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; 

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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
⊢ ∀ (a : Products I), a < l ∧ eval C a = f ↔ a < l ∧ (πs C o) (eval (π C fun x => ord I x < o) a) = f

Next tactic:
intro m
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  

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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
m : Products I
⊢ m < l ∧ eval C m = f ↔ m < l ∧ (πs C o) (eval (π C fun x => ord I x < o) m) = f

Next tactic:
apply and_congr_right
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  apply and_congr_right; 

Proof state:
case h.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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
m : Products I
⊢ m < l → (eval C m = f ↔ (πs C o) (eval (π C fun x => ord I x < o) m) = f)

Next tactic:
intro hm
theorem eval_πs_image {l : Products I} {o : Ordinal}
    (hl : ∀ i ∈ l.val, ord I i < o) : eval C '' { m | m < l } =
    (πs C o) '' (eval (π C (ord I · < o)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  apply and_congr_right; intro hm
  

Proof state:
case h.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)
l : Products I
o : Ordinal.{u}
hl : ∀ i ∈ ↑l, ord I i < o
f : LocallyConstant ↑C ℤ
m : Products I
hm : m < l
⊢ eval C m = f ↔ (πs C o) (eval (π C fun x => ord I x < o) m) = f

Next tactic:
rw [eval_πs C (lt_ord_of_lt hm hl)]
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < 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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
⊢ eval (π C fun x => ord I x < o₂) '' {m | m < l} = ⇑(πs' C h) '' (eval (π C fun x => ord I x < o₁) '' {m | m < l})

Next tactic:
ext f
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
⊢ f ∈ eval (π C fun x => ord I x < o₂) '' {m | m < l} ↔
    f ∈ ⇑(πs' C h) '' (eval (π C fun x => ord I x < o₁) '' {m | m < l})

Next tactic:
simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
⊢ (∃ x < l, eval (π C fun x => ord I x < o₂) x = f) ↔ ∃ a < l, (πs' C h) (eval (π C fun x => ord I x < o₁) a) = f

Next tactic:
apply exists_congr
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; 

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
⊢ ∀ (a : Products I),
    a < l ∧ eval (π C fun x => ord I x < o₂) a = f ↔ a < l ∧ (πs' C h) (eval (π C fun x => ord I x < o₁) a) = f

Next tactic:
intro m
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
m : Products I
⊢ m < l ∧ eval (π C fun x => ord I x < o₂) m = f ↔ m < l ∧ (πs' C h) (eval (π C fun x => ord I x < o₁) m) = f

Next tactic:
apply and_congr_right
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  apply and_congr_right; 

Proof state:
case h.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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
m : Products I
⊢ m < l → (eval (π C fun x => ord I x < o₂) m = f ↔ (πs' C h) (eval (π C fun x => ord I x < o₁) m) = f)

Next tactic:
intro hm
theorem eval_πs_image' {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : ∀ i ∈ l.val, ord I i < o₁) : eval (π C (ord I · < o₂)) '' { m | m < l } =
    (πs' C h) '' (eval (π C (ord I · < o₁)) '' { m | m < l }) := by
  ext f
  simp only [Set.mem_image, Set.mem_setOf_eq, exists_exists_and_eq_and]
  apply exists_congr; intro m
  apply and_congr_right; intro hm
  

Proof state:
case h.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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : ∀ i ∈ ↑l, ord I i < o₁
f : LocallyConstant ↑(π C fun x => ord I x < o₂) ℤ
m : Products I
hm : m < l
⊢ eval (π C fun x => ord I x < o₂) m = f ↔ (πs' C h) (eval (π C fun x => ord I x < o₁) m) = f

Next tactic:
rw [eval_πs' C h (lt_ord_of_lt hm hl)]
/--
If `l` is good w.r.t. `π C (ord I · < o₁)` and `o₁ ≤ o₂`, then it is good w.r.t.
`π C (ord I · < o₂)`
-/
theorem isGood_mono {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : l.isGood (π C (ord I · < o₁))) : l.isGood (π 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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : isGood (π C fun x => ord I x < o₁) l
⊢ isGood (π C fun x => ord I x < o₂) l

Next tactic:
intro hl'
/--
If `l` is good w.r.t. `π C (ord I · < o₁)` and `o₁ ≤ o₂`, then it is good w.r.t.
`π C (ord I · < o₂)`
-/
theorem isGood_mono {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : l.isGood (π C (ord I · < o₁))) : l.isGood (π C (ord I · < o₂)) := by
  intro hl'
  

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : isGood (π C fun x => ord I x < o₁) l
hl' : eval (π C fun x => ord I x < o₂) l ∈ Submodule.span ℤ (eval (π C fun x => ord I x < o₂) '' {m | m < l})
⊢ False

Next tactic:
apply hl
/--
If `l` is good w.r.t. `π C (ord I · < o₁)` and `o₁ ≤ o₂`, then it is good w.r.t.
`π C (ord I · < o₂)`
-/
theorem isGood_mono {l : Products I} {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂)
    (hl : l.isGood (π C (ord I · < o₁))) : l.isGood (π C (ord I · < o₂)) := by
  intro hl'
  apply hl
  

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)
l : Products I
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
hl : isGood (π C fun x => ord I x < o₁) l
hl' : eval (π C fun x => ord I x < o₂) l ∈ Submodule.span ℤ (eval (π C fun x => ord I x < o₂) '' {m | m < l})
⊢ eval (π C fun x => ord I x < o₁) l ∈ Submodule.span ℤ (eval (π C fun x => ord I x < o₁) '' {m | m < l})

Next tactic:
rwa [eval_πs_image' C h (prop_of_isGood  C _ hl), ← eval_πs' C h (prop_of_isGood  C _ hl),
    Submodule.apply_mem_span_image_iff_mem_span (injective_πs' C h)] at hl'
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C 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}
⊢ Function.Bijective (range_equiv_smaller_toFun C o)

Next tactic:
dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  

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}
⊢ Function.Bijective fun x =>
    { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
      property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) }

Next tactic:
refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
  · 

Proof state:
case refine_1
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}
a b : ↑(range (π C fun x => ord I x < o))
hab :
  (fun x =>
        { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
          property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
      a =
    (fun x =>
        { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
          property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
      b
⊢ a = b

Next tactic:
ext1
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
  · ext1
    

Proof state:
case refine_1.a
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}
a b : ↑(range (π C fun x => ord I x < o))
hab :
  (fun x =>
        { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
          property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
      a =
    (fun x =>
        { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
          property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
      b
⊢ ↑a = ↑b

Next tactic:
simp only [Subtype.mk.injEq] at hab
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
  · ext1
    simp only [Subtype.mk.injEq] at hab
    

Proof state:
case refine_1.a
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}
a b : ↑(range (π C fun x => ord I x < o))
hab :
  LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑a =
    LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑b
⊢ ↑a = ↑b

Next tactic:
exact injective_πs C o hab
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
  · ext1
    simp only [Subtype.mk.injEq] at hab
    exact injective_πs C o hab
  · 

Proof state:
case refine_2
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}
x✝ : ↑(smaller C o)
a : LocallyConstant ↑C ℤ
b : LocallyConstant ↑(π C fun x => ord I x < o) ℤ
hb : b ∈ range (π C fun x => ord I x < o) ∧ (πs C o) b = a
⊢ ∃ a_1,
    (fun x =>
          { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
            property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
        a_1 =
      { val := a, property := (_ : ∃ a_2 ∈ range (π C fun x => ord I x < o), (πs C o) a_2 = a) }

Next tactic:
use ⟨b, hb.1⟩
theorem range_equiv_smaller_toFun_bijective (o : Ordinal) :
    Function.Bijective (range_equiv_smaller_toFun C o) := by
  dsimp (config := { unfoldPartialApp := true }) [range_equiv_smaller_toFun]
  refine ⟨fun a b hab ↦ ?_, fun ⟨a, b, hb⟩ ↦ ?_⟩
  · ext1
    simp only [Subtype.mk.injEq] at hab
    exact injective_πs C o hab
  · use ⟨b, hb.1⟩
    

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}
x✝ : ↑(smaller C o)
a : LocallyConstant ↑C ℤ
b : LocallyConstant ↑(π C fun x => ord I x < o) ℤ
hb : b ∈ range (π C fun x => ord I x < o) ∧ (πs C o) b = a
⊢ (fun x =>
        { val := LocallyConstant.comap (ProjRestrict C fun x => ord I x < o) ↑x,
          property := (_ : ∃ a ∈ range (π C fun x => ord I x < o), (πs C o) a = (πs C o) ↑x) })
      { val := b, property := (_ : b ∈ range (π C fun x => ord I x < o)) } =
    { val := a, property := (_ : ∃ a_1 ∈ range (π C fun x => ord I x < o), (πs C o) a_1 = a) }

Next tactic:
simpa only [Subtype.mk.injEq] using hb.2
theorem smaller_factorization (o : Ordinal) :
    (fun (p : smaller C o) ↦ p.1) ∘ (range_equiv_smaller C o).toFun =
    (πs C o) ∘ (fun (p : range (π C (ord I · < o))) ↦ p.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}
⊢ (fun p => ↑p) ∘ (range_equiv_smaller C o).toFun = ⇑(πs C o) ∘ fun p => ↑p

Next tactic:
rfl
theorem linearIndependent_iff_smaller (o : Ordinal) :
    LinearIndependent ℤ (GoodProducts.eval (π C (ord I · < o))) ↔
    LinearIndependent ℤ (fun (p : smaller C o) ↦ p.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}
⊢ LinearIndependent ℤ (eval (π C fun x => ord I x < o)) ↔ LinearIndependent ℤ fun (p : ↑(smaller C o)) => ↑p

Next tactic:
rw [GoodProducts.linearIndependent_iff_range,
    ← LinearMap.linearIndependent_iff (πs C o)
    (LinearMap.ker_eq_bot_of_injective (injective_πs _ _)), ← smaller_factorization C o]
theorem linearIndependent_iff_smaller (o : Ordinal) :
    LinearIndependent ℤ (GoodProducts.eval (π C (ord I · < o))) ↔
    LinearIndependent ℤ (fun (p : smaller C o) ↦ p.1) := by
  rw [GoodProducts.linearIndependent_iff_range,
    ← LinearMap.linearIndependent_iff (πs C o)
    (LinearMap.ker_eq_bot_of_injective (injective_πs _ _)), ← smaller_factorization C o]
  

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}
⊢ LinearIndependent (ι := ↑(range (π C fun x => ord I x < o))) ℤ ((fun p => ↑p) ∘ (range_equiv_smaller C o).toFun) ↔
    LinearIndependent ℤ fun (p : ↑(smaller C o)) => ↑p

Next tactic:
exact linearIndependent_equiv _
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C 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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
⊢ smaller C o₁ ⊆ smaller C o₂

Next tactic:
rintro f ⟨g, hg, rfl⟩
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  

Proof state:
case 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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
g : LocallyConstant ↑(π C fun x => ord I x < o₁) ℤ
hg : g ∈ range (π C fun x => ord I x < o₁)
⊢ (πs C o₁) g ∈ smaller C o₂

Next tactic:
simp only [smaller, Set.mem_image]
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  

Proof state:
case 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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
g : LocallyConstant ↑(π C fun x => ord I x < o₁) ℤ
hg : g ∈ range (π C fun x => ord I x < o₁)
⊢ ∃ x ∈ range (π C fun x => ord I x < o₂), (πs C o₂) x = (πs C o₁) g

Next tactic:
use πs' C h g
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  use πs' C h g
  

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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
g : LocallyConstant ↑(π C fun x => ord I x < o₁) ℤ
hg : g ∈ range (π C fun x => ord I x < o₁)
⊢ (πs' C h) g ∈ range (π C fun x => ord I x < o₂) ∧ (πs C o₂) ((πs' C h) g) = (πs C o₁) g

Next tactic:
obtain ⟨⟨l, gl⟩, rfl⟩ := hg
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  use πs' C h g
  obtain ⟨⟨l, gl⟩, rfl⟩ := hg
  

Proof state:
case h.intro.mk
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
l : Products I
gl : Products.isGood (π C fun x => ord I x < o₁) l
⊢ (πs' C h) (eval (π C fun x => ord I x < o₁) { val := l, property := gl }) ∈ range (π C fun x => ord I x < o₂) ∧
    (πs C o₂) ((πs' C h) (eval (π C fun x => ord I x < o₁) { val := l, property := gl })) =
      (πs C o₁) (eval (π C fun x => ord I x < o₁) { val := l, property := gl })

Next tactic:
refine ⟨?_, ?_⟩
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  use πs' C h g
  obtain ⟨⟨l, gl⟩, rfl⟩ := hg
  refine ⟨?_, ?_⟩
  · 

Proof state:
case h.intro.mk.refine_1
I : Type u
inst✝² : Inhabited I
inst✝¹ : LinearOrder I
inst✝ : IsWellOrder I fun x x_1 => x < x_1
C : Set (I → Bool)
o₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
l : Products I
gl : Products.isGood (π C fun x => ord I x < o₁) l
⊢ (πs' C h) (eval (π C fun x => ord I x < o₁) { val := l, property := gl }) ∈ range (π C fun x => ord I x < o₂)

Next tactic:
use ⟨l, Products.isGood_mono C h gl⟩
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  use πs' C h g
  obtain ⟨⟨l, gl⟩, rfl⟩ := hg
  refine ⟨?_, ?_⟩
  · use ⟨l, Products.isGood_mono C h gl⟩
    

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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
l : Products I
gl : Products.isGood (π C fun x => ord I x < o₁) l
⊢ eval (π C fun x => ord I x < o₂) { val := l, property := (_ : Products.isGood (π C fun x => ord I x < o₂) l) } =
    (πs' C h) (eval (π C fun x => ord I x < o₁) { val := l, property := gl })

Next tactic:
ext x
theorem smaller_mono {o₁ o₂ : Ordinal} (h : o₁ ≤ o₂) : smaller C o₁ ⊆ smaller C o₂ := by
  rintro f ⟨g, hg, rfl⟩
  simp only [smaller, Set.mem_image]
  use πs' C h g
  obtain ⟨⟨l, gl⟩, rfl⟩ := hg
  refine ⟨?_, ?_⟩
  · use ⟨l, Products.isGood_mono C h gl⟩
    ext x
    

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₁ o₂ : Ordinal.{u}
h : o₁ ≤ o₂
l : Products I
gl : Products.isGood (π C fun x => ord I x < o₁) l
x : ↑(π C fun x => ord I x < o₂)
⊢ (eval (π C fun x => ord I x < o₂) { val := l, property := (_ : Products.isGood (π C fun x => ord I x < o₂) l) }) x =
    ((πs' C h) (eval (π C fun x => ord I x < o₁) { val := l, property := gl })) x

Next tactic:
rw [eval, ← Products.eval_πs' _ h (Products.prop_of_isGood  C _ gl), eval]