l3lab/ntp-mathlib huggingface dataset:
/-- `Mat_.lift F` is the unique additive functor `L : Mat_ C ⥤ D` such that `F ≅ embedding C ⋙ L`.
-/
def liftUnique (F : C ⥤ D) [Functor.Additive F] (L : Mat_ C ⥤ D) [Functor.Additive L]
    (α : embedding C ⋙ L ≅ F) : L ≅ lift F :=
  NatIso.ofComponents
    (fun M =>
      additiveObjIsoBiproduct L M ≪≫
        (biproduct.mapIso fun i => α.app (M.X i)) ≪≫
          (biproduct.mapIso fun i => (embeddingLiftIso F).symm.app (M.X i)) ≪≫
            (additiveObjIsoBiproduct (lift F) M).symm)
    fun f => by
      dsimp only [Iso.trans_hom, Iso.symm_hom, biproduct.mapIso_hom]
      simp only [additiveObjIsoBiproduct_naturality_assoc]
      simp only [biproduct.matrix_map_assoc, Category.assoc]
      simp only [additiveObjIsoBiproduct_naturality']
      simp only [biproduct.map_matrix_assoc, Category.assoc]
      congr 3
      ext j k
      apply biproduct.hom_ext
      rintro ⟨⟩
      dsimp
      

Proof state:
case e_a.e_a.e_m.h.h.w.unit
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
inst✝⁵ : Preadditive C
D : Type u₁
inst✝⁴ : Category.{v₁, u₁} D
inst✝³ : Preadditive D
inst✝² : HasFiniteBiproducts D
F : C ⥤ D
inst✝¹ : Functor.Additive F
L : Mat_ C ⥤ D
inst✝ : Functor.Additive L
α : embedding C ⋙ L ≅ F
X✝ Y✝ : Mat_ C
f : X✝ ⟶ Y✝
j : X✝.ι
k : Y✝.ι
⊢ (L.map ((embedding C).map (f j k)) ≫ α.hom.app (X Y✝ k) ≫ biproduct.lift fun x => 𝟙 (F.obj (X Y✝ k))) ≫
      biproduct.π (fun i => F.obj (X Y✝ k)) PUnit.unit =
    (α.hom.app (X X✝ j) ≫ (biproduct.lift fun x => 𝟙 (F.obj (X X✝ j))) ≫ biproduct.matrix fun i j_1 => F.map (f j k)) ≫
      biproduct.π (fun i => F.obj (X Y✝ k)) PUnit.unit

Next tactic:
simpa using α.hom.naturality (f j k)
instance (R : Type u) : Inhabited (Mat R) := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
R : Type u
⊢ Inhabited (Mat R)

Next tactic:
dsimp [Mat]
instance (R : Type u) : Inhabited (Mat R) := by
  dsimp [Mat]
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
inst✝ : Preadditive C
R : Type u
⊢ Inhabited FintypeCat

Next tactic:
infer_instance
instance (R : Type u) [Semiring R] : Category (Mat R) where
  Hom X Y := Matrix X Y R
  id X := (1 : Matrix X X R)
  comp {X Y Z} f g := (show Matrix X Y R from f) * (show Matrix Y Z R from g)
  assoc := by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type u
inst✝ : Semiring R
⊢ ∀ {W X Y Z : Mat R} (f : W ⟶ X) (g : X ⟶ Y) (h : Y ⟶ Z), (f ≫ g) ≫ h = f ≫ g ≫ h

Next tactic:
intros
instance (R : Type u) [Semiring R] : Category (Mat R) where
  Hom X Y := Matrix X Y R
  id X := (1 : Matrix X X R)
  comp {X Y Z} f g := (show Matrix X Y R from f) * (show Matrix Y Z R from g)
  assoc := by intros; 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type u
inst✝ : Semiring R
W✝ X✝ Y✝ Z✝ : Mat R
f✝ : W✝ ⟶ X✝
g✝ : X✝ ⟶ Y✝
h✝ : Y✝ ⟶ Z✝
⊢ (f✝ ≫ g✝) ≫ h✝ = f✝ ≫ g✝ ≫ h✝

Next tactic:
simp [Matrix.mul_assoc]
@[simp]
theorem id_apply_self (M : Mat R) (i : M) : (𝟙 M : Matrix M M R) i i = 1 := by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type u
inst✝ : Semiring R
M : Mat R
i : ↑M
⊢ 𝟙 M i i = 1

Next tactic:
simp [id_apply]
@[simp]
theorem id_apply_of_ne (M : Mat R) (i j : M) (h : i ≠ j) : (𝟙 M : Matrix M M R) i j = 0 := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type u
inst✝ : Semiring R
M : Mat R
i j : ↑M
h : i ≠ j
⊢ 𝟙 M i j = 0

Next tactic:
simp [id_apply, h]
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat_ (SingleObj Rᵐᵒᵖ)
⊢ { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map (𝟙 X) =
    𝟙 ({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X)

Next tactic:
ext
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    

Proof state:
case h
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat_ (SingleObj Rᵐᵒᵖ)
i✝ j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X)
⊢ { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map (𝟙 X) i✝ j✝ =
    𝟙 ({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X) i✝ j✝

Next tactic:
simp only [Mat_.id_def, id_def]
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    

Proof state:
case h
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat_ (SingleObj Rᵐᵒᵖ)
i✝ j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X)
⊢ MulOpposite.unop (if h : i✝ = j✝ then eqToHom (_ : Mat_.X X i✝ = Mat_.X X j✝) else 0) = if i✝ = j✝ then 1 else 0

Next tactic:
split_ifs
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    split_ifs <;> 

Proof state:
case pos
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat_ (SingleObj Rᵐᵒᵖ)
i✝ j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X)
h✝ : i✝ = j✝
⊢ MulOpposite.unop (eqToHom (_ : Mat_.X X i✝ = Mat_.X X j✝)) = 1

Next tactic:
rfl
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    split_ifs <;> 

Proof state:
case neg
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat_ (SingleObj Rᵐᵒᵖ)
i✝ j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X)
h✝ : ¬i✝ = j✝
⊢ MulOpposite.unop 0 = 0

Next tactic:
rfl
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    split_ifs <;> rfl
  map_comp f g := by
    -- Porting note: this proof was automatic in mathlib3
    

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ Z✝ : Mat_ (SingleObj Rᵐᵒᵖ)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
⊢ { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map (f ≫ g) =
    { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map f ≫
      { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map g

Next tactic:
ext
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    split_ifs <;> rfl
  map_comp f g := by
    -- Porting note: this proof was automatic in mathlib3
    ext
    

Proof state:
case h
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ Z✝ : Mat_ (SingleObj Rᵐᵒᵖ)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
i✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X✝)
j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj Z✝)
⊢ { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map (f ≫ g) i✝ j✝ =
    ({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map f ≫
        { obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.map g)
      i✝ j✝

Next tactic:
simp only [Mat_.comp_apply, comp_apply]
/-- Auxiliary definition for `CategoryTheory.Mat.equivalenceSingleObj`. -/
@[simps]
def equivalenceSingleObjInverse : Mat_ (SingleObj Rᵐᵒᵖ) ⥤ Mat R where
  obj X := FintypeCat.of X.ι
  map f i j := MulOpposite.unop (f i j)
  map_id X := by
    ext
    simp only [Mat_.id_def, id_def]
    split_ifs <;> rfl
  map_comp f g := by
    -- Porting note: this proof was automatic in mathlib3
    ext
    simp only [Mat_.comp_apply, comp_apply]
    

Proof state:
case h
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ Z✝ : Mat_ (SingleObj Rᵐᵒᵖ)
f : X✝ ⟶ Y✝
g : Y✝ ⟶ Z✝
i✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj X✝)
j✝ : ↑({ obj := fun X => FintypeCat.of X.ι, map := fun {X Y} f i j => MulOpposite.unop (f i j) }.obj Z✝)
⊢ MulOpposite.unop (∑ j : Y✝.ι, f i✝ j ≫ g j j✝) =
    ∑ j : ↑(FintypeCat.of Y✝.ι), MulOpposite.unop (f i✝ j) * MulOpposite.unop (g j j✝)

Next tactic:
apply Finset.unop_sum
instance : Faithful (equivalenceSingleObjInverse R) where
  map_injective w := by
    

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ : Mat_ (SingleObj Rᵐᵒᵖ)
a₁✝ a₂✝ : X✝ ⟶ Y✝
w : (equivalenceSingleObjInverse R).map a₁✝ = (equivalenceSingleObjInverse R).map a₂✝
⊢ a₁✝ = a₂✝

Next tactic:
ext
instance : Faithful (equivalenceSingleObjInverse R) where
  map_injective w := by
    ext
    

Proof state:
case H
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ : Mat_ (SingleObj Rᵐᵒᵖ)
a₁✝ a₂✝ : X✝ ⟶ Y✝
w : (equivalenceSingleObjInverse R).map a₁✝ = (equivalenceSingleObjInverse R).map a₂✝
i✝ : X✝.ι
j✝ : Y✝.ι
⊢ a₁✝ i✝ j✝ = a₂✝ i✝ j✝

Next tactic:
apply_fun MulOpposite.unop using MulOpposite.unop_injective
instance : Faithful (equivalenceSingleObjInverse R) where
  map_injective w := by
    ext
    apply_fun MulOpposite.unop using MulOpposite.unop_injective
    

Proof state:
case H
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X✝ Y✝ : Mat_ (SingleObj Rᵐᵒᵖ)
a₁✝ a₂✝ : X✝ ⟶ Y✝
w : (equivalenceSingleObjInverse R).map a₁✝ = (equivalenceSingleObjInverse R).map a₂✝
i✝ : X✝.ι
j✝ : Y✝.ι
⊢ MulOpposite.unop (a₁✝ i✝ j✝) = MulOpposite.unop (a₂✝ i✝ j✝)

Next tactic:
exact congr_fun (congr_fun w _) _
instance : EssSurj (equivalenceSingleObjInverse R) where
  mem_essImage X :=
    ⟨{  ι := X
        X := fun _ => PUnit.unit }, ⟨eqToIso (by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat R
⊢ (equivalenceSingleObjInverse R).obj (Mat_.mk ↑X fun x => PUnit.unit) = X

Next tactic:
dsimp
instance : EssSurj (equivalenceSingleObjInverse R) where
  mem_essImage X :=
    ⟨{  ι := X
        X := fun _ => PUnit.unit }, ⟨eqToIso (by dsimp; 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X : Mat R
⊢ FintypeCat.of ↑X = X

Next tactic:
cases X
instance : EssSurj (equivalenceSingleObjInverse R) where
  mem_essImage X :=
    ⟨{  ι := X
        X := fun _ => PUnit.unit }, ⟨eqToIso (by dsimp; cases X; 

Proof state:
case mk
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
α✝ : Type
str✝ : Fintype α✝
⊢ FintypeCat.of ↑(Bundled.mk α✝) = Bundled.mk α✝

Next tactic:
congr
instance (X Y : Mat R) : AddCommGroup (X ⟶ Y) := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X Y : Mat R
⊢ AddCommGroup (X ⟶ Y)

Next tactic:
change AddCommGroup (Matrix X Y R)
instance (X Y : Mat R) : AddCommGroup (X ⟶ Y) := by
  change AddCommGroup (Matrix X Y R)
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
inst✝¹ : Preadditive C
R : Type
inst✝ : Ring R
X Y : Mat R
⊢ AddCommGroup (Matrix (↑X) (↑Y) R)

Next tactic:
infer_instance
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
tfae_have 1 ↔ 2
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; 

Proof state:
case tfae_1_iff_2
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ I ≤ J ↔ ↑I ⊆ ↑J
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
exact Iff.rfl
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
tfae_have 2 → 3
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · 

Proof state:
case tfae_2_to_3
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
⊢ ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper

Next tactic:
intro h
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    

Proof state:
case tfae_2_to_3
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
h : ↑I ⊆ ↑J
⊢ Icc I.lower I.upper ⊆ Icc J.lower J.upper

Next tactic:
simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
tfae_have 3 ↔ 4
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
  tfae_have 3 ↔ 4; 

Proof state:
case tfae_3_iff_4
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
⊢ Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
tfae_3_iff_4 : Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
exact Icc_subset_Icc_iff I.lower_le_upper
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
  tfae_have 3 ↔ 4; exact Icc_subset_Icc_iff I.lower_le_upper
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
tfae_3_iff_4 : Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
tfae_have 4 → 2
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
  tfae_have 3 ↔ 4; exact Icc_subset_Icc_iff I.lower_le_upper
  tfae_have 4 → 2; 

Proof state:
case tfae_4_to_2
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
tfae_3_iff_4 : Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
⊢ J.lower ≤ I.lower ∧ I.upper ≤ J.upper → ↑I ⊆ ↑J
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
tfae_3_iff_4 : Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
tfae_4_to_2 : J.lower ≤ I.lower ∧ I.upper ≤ J.upper → ↑I ⊆ ↑J
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
exact fun h x hx i ↦ Ioc_subset_Ioc (h.1 i) (h.2 i) (hx i)
theorem le_TFAE : List.TFAE [I ≤ J, (I : Set (ι → ℝ)) ⊆ J,
    Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper] := by
  tfae_have 1 ↔ 2; exact Iff.rfl
  tfae_have 2 → 3
  · intro h
    simpa [coe_eq_pi, closure_pi_set, lower_ne_upper] using closure_mono h
  tfae_have 3 ↔ 4; exact Icc_subset_Icc_iff I.lower_le_upper
  tfae_have 4 → 2; exact fun h x hx i ↦ Ioc_subset_Ioc (h.1 i) (h.2 i) (hx i)
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
tfae_1_iff_2 : I ≤ J ↔ ↑I ⊆ ↑J
tfae_2_to_3 : ↑I ⊆ ↑J → Icc I.lower I.upper ⊆ Icc J.lower J.upper
tfae_3_iff_4 : Icc I.lower I.upper ⊆ Icc J.lower J.upper ↔ J.lower ≤ I.lower ∧ I.upper ≤ J.upper
tfae_4_to_2 : J.lower ≤ I.lower ∧ I.upper ≤ J.upper → ↑I ⊆ ↑J
⊢ List.TFAE [I ≤ J, ↑I ⊆ ↑J, Icc I.lower I.upper ⊆ Icc J.lower J.upper, J.lower ≤ I.lower ∧ I.upper ≤ J.upper]

Next tactic:
tfae_finish
theorem injective_coe : Injective ((↑) : Box ι → Set (ι → ℝ)) := by
  

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ Injective toSet

Next tactic:
rintro ⟨l₁, u₁, h₁⟩ ⟨l₂, u₂, h₂⟩ h
theorem injective_coe : Injective ((↑) : Box ι → Set (ι → ℝ)) := by
  rintro ⟨l₁, u₁, h₁⟩ ⟨l₂, u₂, h₂⟩ h
  

Proof state:
case mk.mk
ι : Type u_1
I J : Box ι
x y l₁ u₁ : ι → ℝ
h₁ : ∀ (i : ι), l₁ i < u₁ i
l₂ u₂ : ι → ℝ
h₂ : ∀ (i : ι), l₂ i < u₂ i
h : ↑{ lower := l₁, upper := u₁, lower_lt_upper := h₁ } = ↑{ lower := l₂, upper := u₂, lower_lt_upper := h₂ }
⊢ { lower := l₁, upper := u₁, lower_lt_upper := h₁ } = { lower := l₂, upper := u₂, lower_lt_upper := h₂ }

Next tactic:
simp only [Subset.antisymm_iff, coe_subset_coe, le_iff_bounds] at h
theorem injective_coe : Injective ((↑) : Box ι → Set (ι → ℝ)) := by
  rintro ⟨l₁, u₁, h₁⟩ ⟨l₂, u₂, h₂⟩ h
  simp only [Subset.antisymm_iff, coe_subset_coe, le_iff_bounds] at h
  

Proof state:
case mk.mk
ι : Type u_1
I J : Box ι
x y l₁ u₁ : ι → ℝ
h₁ : ∀ (i : ι), l₁ i < u₁ i
l₂ u₂ : ι → ℝ
h₂ : ∀ (i : ι), l₂ i < u₂ i
h : (l₂ ≤ l₁ ∧ u₁ ≤ u₂) ∧ l₁ ≤ l₂ ∧ u₂ ≤ u₁
⊢ { lower := l₁, upper := u₁, lower_lt_upper := h₁ } = { lower := l₂, upper := u₂, lower_lt_upper := h₂ }

Next tactic:
congr
theorem injective_coe : Injective ((↑) : Box ι → Set (ι → ℝ)) := by
  rintro ⟨l₁, u₁, h₁⟩ ⟨l₂, u₂, h₂⟩ h
  simp only [Subset.antisymm_iff, coe_subset_coe, le_iff_bounds] at h
  congr
  

Proof state:
case mk.mk.e_lower
ι : Type u_1
I J : Box ι
x y l₁ u₁ : ι → ℝ
h₁ : ∀ (i : ι), l₁ i < u₁ i
l₂ u₂ : ι → ℝ
h₂ : ∀ (i : ι), l₂ i < u₂ i
h : (l₂ ≤ l₁ ∧ u₁ ≤ u₂) ∧ l₁ ≤ l₂ ∧ u₂ ≤ u₁
⊢ l₁ = l₂
case mk.mk.e_upper
ι : Type u_1
I J : Box ι
x y l₁ u₁ : ι → ℝ
h₁ : ∀ (i : ι), l₁ i < u₁ i
l₂ u₂ : ι → ℝ
h₂ : ∀ (i : ι), l₂ i < u₂ i
h : (l₂ ≤ l₁ ∧ u₁ ≤ u₂) ∧ l₁ ≤ l₂ ∧ u₂ ≤ u₁
⊢ u₁ = u₂

Next tactic:
exacts [le_antisymm h.2.1 h.1.1, le_antisymm h.1.2 h.2.2]
theorem isSome_iff : ∀ {I : WithBot (Box ι)}, I.isSome ↔ (I : Set (ι → ℝ)).Nonempty
  | ⊥ => by
    

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ Option.isSome ⊥ = true ↔ Set.Nonempty ↑⊥

Next tactic:
erw [Option.isSome]
theorem isSome_iff : ∀ {I : WithBot (Box ι)}, I.isSome ↔ (I : Set (ι → ℝ)).Nonempty
  | ⊥ => by
    erw [Option.isSome]
    

Proof state:
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ (match ⊥ with
      | some val => true
      | none => false) =
      true ↔
    Set.Nonempty ↑⊥

Next tactic:
simp
theorem isSome_iff : ∀ {I : WithBot (Box ι)}, I.isSome ↔ (I : Set (ι → ℝ)).Nonempty
  | ⊥ => by
    erw [Option.isSome]
    simp
  | (I : Box ι) => by
    

Proof state:
ι : Type u_1
I✝ J : Box ι
x y : ι → ℝ
I : Box ι
⊢ Option.isSome ↑I = true ↔ Set.Nonempty ↑↑I

Next tactic:
erw [Option.isSome]
theorem isSome_iff : ∀ {I : WithBot (Box ι)}, I.isSome ↔ (I : Set (ι → ℝ)).Nonempty
  | ⊥ => by
    erw [Option.isSome]
    simp
  | (I : Box ι) => by
    erw [Option.isSome]
    

Proof state:
ι : Type u_1
I✝ J : Box ι
x y : ι → ℝ
I : Box ι
⊢ (match ↑I with
      | some val => true
      | none => false) =
      true ↔
    Set.Nonempty ↑↑I

Next tactic:
simp [I.nonempty_coe]
theorem biUnion_coe_eq_coe (I : WithBot (Box ι)) :
    ⋃ (J : Box ι) (_ : ↑J = I), (J : Set (ι → ℝ)) = I := by
  

Proof state:
ι : Type u_1
I✝ J : Box ι
x y : ι → ℝ
I : WithBot (Box ι)
⊢ ⋃ J, ⋃ (_ : ↑J = I), ↑J = ↑I

Next tactic:
induction I using WithBot.recBotCoe
theorem biUnion_coe_eq_coe (I : WithBot (Box ι)) :
    ⋃ (J : Box ι) (_ : ↑J = I), (J : Set (ι → ℝ)) = I := by
  induction I using WithBot.recBotCoe <;> 

Proof state:
case bot
ι : Type u_1
I J : Box ι
x y : ι → ℝ
⊢ ⋃ J, ⋃ (_ : ↑J = ⊥), ↑J = ↑⊥

Next tactic:
simp [WithBot.coe_eq_coe]
theorem biUnion_coe_eq_coe (I : WithBot (Box ι)) :
    ⋃ (J : Box ι) (_ : ↑J = I), (J : Set (ι → ℝ)) = I := by
  induction I using WithBot.recBotCoe <;> 

Proof state:
case coe
ι : Type u_1
I J : Box ι
x y : ι → ℝ
a✝ : Box ι
⊢ ⋃ J, ⋃ (_ : ↑J = ↑a✝), ↑J = ↑↑a✝

Next tactic:
simp [WithBot.coe_eq_coe]
@[simp, norm_cast]
theorem withBotCoe_subset_iff {I J : WithBot (Box ι)} : (I : Set (ι → ℝ)) ⊆ J ↔ I ≤ J := by
  

Proof state:
ι : Type u_1
I✝ J✝ : Box ι
x y : ι → ℝ
I J : WithBot (Box ι)
⊢ ↑I ⊆ ↑J ↔ I ≤ J

Next tactic:
induction I using WithBot.recBotCoe
@[simp, norm_cast]
theorem withBotCoe_subset_iff {I J : WithBot (Box ι)} : (I : Set (ι → ℝ)) ⊆ J ↔ I ≤ J := by
  induction I using WithBot.recBotCoe; · 

Proof state:
case bot
ι : Type u_1
I J✝ : Box ι
x y : ι → ℝ
J : WithBot (Box ι)
⊢ ↑⊥ ⊆ ↑J ↔ ⊥ ≤ J

Next tactic:
simp
@[simp, norm_cast]
theorem withBotCoe_subset_iff {I J : WithBot (Box ι)} : (I : Set (ι → ℝ)) ⊆ J ↔ I ≤ J := by
  induction I using WithBot.recBotCoe; · simp
  

Proof state:
case coe
ι : Type u_1
I J✝ : Box ι
x y : ι → ℝ
J : WithBot (Box ι)
a✝ : Box ι
⊢ ↑↑a✝ ⊆ ↑J ↔ ↑a✝ ≤ J

Next tactic:
induction J using WithBot.recBotCoe
@[simp, norm_cast]
theorem withBotCoe_subset_iff {I J : WithBot (Box ι)} : (I : Set (ι → ℝ)) ⊆ J ↔ I ≤ J := by
  induction I using WithBot.recBotCoe; · simp
  induction J using WithBot.recBotCoe; · 

Proof state:
case coe.bot
ι : Type u_1
I J : Box ι
x y : ι → ℝ
a✝ : Box ι
⊢ ↑↑a✝ ⊆ ↑⊥ ↔ ↑a✝ ≤ ⊥

Next tactic:
simp [subset_empty_iff]
@[simp, norm_cast]
theorem withBotCoe_subset_iff {I J : WithBot (Box ι)} : (I : Set (ι → ℝ)) ⊆ J ↔ I ≤ J := by
  induction I using WithBot.recBotCoe; · simp
  induction J using WithBot.recBotCoe; · simp [subset_empty_iff]
  

Proof state:
case coe.coe
ι : Type u_1
I J : Box ι
x y : ι → ℝ
a✝¹ a✝ : Box ι
⊢ ↑↑a✝¹ ⊆ ↑↑a✝ ↔ ↑a✝¹ ≤ ↑a✝

Next tactic:
simp [le_def]