l3lab/ntp-mathlib huggingface dataset:
/-- The categorical kernel of a morphism in `AddCommGroupCat`
agrees with the usual group-theoretical kernel.
-/
def kernelIsoKer {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    kernel f ≅ AddCommGroupCat.of f.ker where
  hom :=
    { toFun := fun g => ⟨kernel.ι f g, FunLike.congr_fun (kernel.condition f) g⟩
      map_zero' := by
        refine Subtype.ext ?_
        simp [(AddSubgroup.coe_zero _).symm]
      map_add' := fun g g' => by
        refine Subtype.ext ?_
        change _ = _ + _
        dsimp
        simp }
  inv := kernel.lift f (AddSubgroup.subtype f.ker) <| by
    -- porting note : used to be `tidy`, but `aesop` can't do it
    refine FunLike.ext _ _ ?_
    rintro ⟨x, (hx : f _ = 0)⟩
    exact hx
  hom_inv_id := by
    -- Porting note: it would be nice to do the next two steps by a single `ext`,
    -- but this will require thinking carefully about the relative priorities of `@[ext]` lemmas.
    refine equalizer.hom_ext ?_
    ext x
    dsimp
    generalize_proofs _ h1 h2
    erw [FunLike.congr_fun (kernel.lift_ι f _ h1) ⟨_, h2⟩]
    rfl
  inv_hom_id := by
    apply AddCommGroupCat.ext
    simp only [AddMonoidHom.coe_mk, coe_id, coe_comp]
    rintro ⟨x, mem⟩
    refine Subtype.ext ?_
    simp only [ZeroHom.coe_mk, Function.comp_apply, id_eq]
    

Proof state:
case w.mk
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
x : ↑G
mem : x ∈ AddMonoidHom.ker f
⊢ (kernel.ι f)
      ((kernel.lift f (AddSubgroup.subtype (AddMonoidHom.ker f)) (_ : AddSubgroup.subtype (AddMonoidHom.ker f) ≫ f = 0))
        { val := x, property := mem }) =
    x

Next tactic:
generalize_proofs _ h1 h2
/-- The categorical kernel of a morphism in `AddCommGroupCat`
agrees with the usual group-theoretical kernel.
-/
def kernelIsoKer {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    kernel f ≅ AddCommGroupCat.of f.ker where
  hom :=
    { toFun := fun g => ⟨kernel.ι f g, FunLike.congr_fun (kernel.condition f) g⟩
      map_zero' := by
        refine Subtype.ext ?_
        simp [(AddSubgroup.coe_zero _).symm]
      map_add' := fun g g' => by
        refine Subtype.ext ?_
        change _ = _ + _
        dsimp
        simp }
  inv := kernel.lift f (AddSubgroup.subtype f.ker) <| by
    -- porting note : used to be `tidy`, but `aesop` can't do it
    refine FunLike.ext _ _ ?_
    rintro ⟨x, (hx : f _ = 0)⟩
    exact hx
  hom_inv_id := by
    -- Porting note: it would be nice to do the next two steps by a single `ext`,
    -- but this will require thinking carefully about the relative priorities of `@[ext]` lemmas.
    refine equalizer.hom_ext ?_
    ext x
    dsimp
    generalize_proofs _ h1 h2
    erw [FunLike.congr_fun (kernel.lift_ι f _ h1) ⟨_, h2⟩]
    rfl
  inv_hom_id := by
    apply AddCommGroupCat.ext
    simp only [AddMonoidHom.coe_mk, coe_id, coe_comp]
    rintro ⟨x, mem⟩
    refine Subtype.ext ?_
    simp only [ZeroHom.coe_mk, Function.comp_apply, id_eq]
    generalize_proofs _ h1 h2
    

Proof state:
case w.mk
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
x : ↑G
mem : x ∈ AddMonoidHom.ker f
h✝ : HasKernel f
h1 : AddSubgroup.subtype (AddMonoidHom.ker f) ≫ f = 0
⊢ (kernel.ι f) ((kernel.lift f (AddSubgroup.subtype (AddMonoidHom.ker f)) h1) { val := x, property := mem }) = x

Next tactic:
erw [FunLike.congr_fun (kernel.lift_ι f _ h1) ⟨_, mem⟩]
/-- The categorical kernel of a morphism in `AddCommGroupCat`
agrees with the usual group-theoretical kernel.
-/
def kernelIsoKer {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    kernel f ≅ AddCommGroupCat.of f.ker where
  hom :=
    { toFun := fun g => ⟨kernel.ι f g, FunLike.congr_fun (kernel.condition f) g⟩
      map_zero' := by
        refine Subtype.ext ?_
        simp [(AddSubgroup.coe_zero _).symm]
      map_add' := fun g g' => by
        refine Subtype.ext ?_
        change _ = _ + _
        dsimp
        simp }
  inv := kernel.lift f (AddSubgroup.subtype f.ker) <| by
    -- porting note : used to be `tidy`, but `aesop` can't do it
    refine FunLike.ext _ _ ?_
    rintro ⟨x, (hx : f _ = 0)⟩
    exact hx
  hom_inv_id := by
    -- Porting note: it would be nice to do the next two steps by a single `ext`,
    -- but this will require thinking carefully about the relative priorities of `@[ext]` lemmas.
    refine equalizer.hom_ext ?_
    ext x
    dsimp
    generalize_proofs _ h1 h2
    erw [FunLike.congr_fun (kernel.lift_ι f _ h1) ⟨_, h2⟩]
    rfl
  inv_hom_id := by
    apply AddCommGroupCat.ext
    simp only [AddMonoidHom.coe_mk, coe_id, coe_comp]
    rintro ⟨x, mem⟩
    refine Subtype.ext ?_
    simp only [ZeroHom.coe_mk, Function.comp_apply, id_eq]
    generalize_proofs _ h1 h2
    erw [FunLike.congr_fun (kernel.lift_ι f _ h1) ⟨_, mem⟩]
    

Proof state:
case w.mk
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
x : ↑G
mem : x ∈ AddMonoidHom.ker f
h✝ : HasKernel f
h1 : AddSubgroup.subtype (AddMonoidHom.ker f) ≫ f = 0
⊢ (AddSubgroup.subtype (AddMonoidHom.ker f)) { val := x, property := mem } = x

Next tactic:
rfl
@[simp]
theorem kernelIsoKer_hom_comp_subtype {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    (kernelIsoKer f).hom ≫ AddSubgroup.subtype f.ker = kernel.ι f := by 

Proof state:
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
⊢ (kernelIsoKer f).hom ≫ AddSubgroup.subtype (AddMonoidHom.ker f) = kernel.ι f

Next tactic:
ext
@[simp]
theorem kernelIsoKer_hom_comp_subtype {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    (kernelIsoKer f).hom ≫ AddSubgroup.subtype f.ker = kernel.ι f := by ext; 

Proof state:
case w
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
x✝ : ↑(kernel f)
⊢ ((kernelIsoKer f).hom ≫ AddSubgroup.subtype (AddMonoidHom.ker f)) x✝ = (kernel.ι f) x✝

Next tactic:
rfl
@[simp]
theorem kernelIsoKer_inv_comp_ι {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    (kernelIsoKer f).inv ≫ kernel.ι f = AddSubgroup.subtype f.ker := by
  

Proof state:
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
⊢ (kernelIsoKer f).inv ≫ kernel.ι f = AddSubgroup.subtype (AddMonoidHom.ker f)

Next tactic:
ext
@[simp]
theorem kernelIsoKer_inv_comp_ι {G H : AddCommGroupCat.{u}} (f : G ⟶ H) :
    (kernelIsoKer f).inv ≫ kernel.ι f = AddSubgroup.subtype f.ker := by
  ext
  

Proof state:
case w
J : Type v
inst✝ : SmallCategory J
G H : AddCommGroupCat
f : G ⟶ H
x✝ : ↑(of ↥(AddMonoidHom.ker f))
⊢ ((kernelIsoKer f).inv ≫ kernel.ι f) x✝ = (AddSubgroup.subtype (AddMonoidHom.ker f)) x✝

Next tactic:
simp [kernelIsoKer]
theorem universallyClosed_eq : @UniversallyClosed = universally (topologically @IsClosedMap) := by
  

Proof state:
X Y : Scheme
f : X ⟶ Y
⊢ @UniversallyClosed = universally (topologically @IsClosedMap)

Next tactic:
ext X Y f
theorem universallyClosed_eq : @UniversallyClosed = universally (topologically @IsClosedMap) := by
  ext X Y f; 

Proof state:
case h.h.h.a
X✝ Y✝ : Scheme
f✝ : X✝ ⟶ Y✝
X Y : Scheme
f : X ⟶ Y
⊢ UniversallyClosed f ↔ universally (topologically @IsClosedMap) f

Next tactic:
rw [UniversallyClosed_iff]
theorem universallyClosed_stableUnderComposition : StableUnderComposition @UniversallyClosed := by
  

Proof state:
X Y : Scheme
f : X ⟶ Y
⊢ StableUnderComposition @UniversallyClosed

Next tactic:
rw [universallyClosed_eq]
theorem universallyClosed_stableUnderComposition : StableUnderComposition @UniversallyClosed := by
  rw [universallyClosed_eq]
  

Proof state:
X Y : Scheme
f : X ⟶ Y
⊢ StableUnderComposition (universally (topologically @IsClosedMap))

Next tactic:
exact StableUnderComposition.universally (fun X Y Z f g hf hg =>
    @IsClosedMap.comp _ _ _ _ _ _ g.1.base f.1.base hg hf)
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  

Proof state:
X Y : Scheme
f : X ⟶ Y
⊢ PropertyIsLocalAtTarget @UniversallyClosed

Next tactic:
rw [universallyClosed_eq]
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  rw [universallyClosed_eq]
  

Proof state:
X Y : Scheme
f : X ⟶ Y
⊢ PropertyIsLocalAtTarget (universally (topologically @IsClosedMap))

Next tactic:
apply universallyIsLocalAtTargetOfMorphismRestrict
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  rw [universallyClosed_eq]
  apply universallyIsLocalAtTargetOfMorphismRestrict
  · 

Proof state:
case hP₁
X Y : Scheme
f : X ⟶ Y
⊢ RespectsIso (topologically @IsClosedMap)

Next tactic:
exact StableUnderComposition.respectsIso (fun X Y Z f g hf hg =>
        @IsClosedMap.comp _ _ _ _ _ _ g.1.base f.1.base hg hf)
      (fun f => (TopCat.homeoOfIso (Scheme.forgetToTop.mapIso f)).isClosedMap)
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  rw [universallyClosed_eq]
  apply universallyIsLocalAtTargetOfMorphismRestrict
  · exact StableUnderComposition.respectsIso (fun X Y Z f g hf hg =>
        @IsClosedMap.comp _ _ _ _ _ _ g.1.base f.1.base hg hf)
      (fun f => (TopCat.homeoOfIso (Scheme.forgetToTop.mapIso f)).isClosedMap)
  · 

Proof state:
case hP₂
X Y : Scheme
f : X ⟶ Y
⊢ ∀ {X Y : Scheme} (f : X ⟶ Y) {ι : Type u_1} (U : ι → Opens ↑↑Y.toPresheafedSpace),
    iSup U = ⊤ → (∀ (i : ι), topologically (@IsClosedMap) (f ∣_ U i)) → topologically (@IsClosedMap) f

Next tactic:
intro X Y f ι U hU H
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  rw [universallyClosed_eq]
  apply universallyIsLocalAtTargetOfMorphismRestrict
  · exact StableUnderComposition.respectsIso (fun X Y Z f g hf hg =>
        @IsClosedMap.comp _ _ _ _ _ _ g.1.base f.1.base hg hf)
      (fun f => (TopCat.homeoOfIso (Scheme.forgetToTop.mapIso f)).isClosedMap)
  · intro X Y f ι U hU H
    

Proof state:
case hP₂
X✝ Y✝ : Scheme
f✝ : X✝ ⟶ Y✝
X Y : Scheme
f : X ⟶ Y
ι : Type u_1
U : ι → Opens ↑↑Y.toPresheafedSpace
hU : iSup U = ⊤
H : ∀ (i : ι), topologically (@IsClosedMap) (f ∣_ U i)
⊢ topologically (@IsClosedMap) f

Next tactic:
simp_rw [topologically, morphismRestrict_base] at H
theorem universallyClosed_is_local_at_target : PropertyIsLocalAtTarget @UniversallyClosed := by
  rw [universallyClosed_eq]
  apply universallyIsLocalAtTargetOfMorphismRestrict
  · exact StableUnderComposition.respectsIso (fun X Y Z f g hf hg =>
        @IsClosedMap.comp _ _ _ _ _ _ g.1.base f.1.base hg hf)
      (fun f => (TopCat.homeoOfIso (Scheme.forgetToTop.mapIso f)).isClosedMap)
  · intro X Y f ι U hU H
    simp_rw [topologically, morphismRestrict_base] at H
    

Proof state:
case hP₂
X✝ Y✝ : Scheme
f✝ : X✝ ⟶ Y✝
X Y : Scheme
f : X ⟶ Y
ι : Type u_1
U : ι → Opens ↑↑Y.toPresheafedSpace
hU : iSup U = ⊤
H : ∀ (i : ι), IsClosedMap (Set.restrictPreimage (U i).carrier ⇑f.val.base)
⊢ topologically (@IsClosedMap) f

Next tactic:
exact (isClosedMap_iff_isClosedMap_of_iSup_eq_top hU).mpr H
theorem ext' : Function.Injective ((↑) : ProperCone 𝕜 E → ConvexCone 𝕜 E) := fun S T h => by
  

Proof state:
𝕜 : Type u_1
inst✝³ : OrderedSemiring 𝕜
E : Type u_2
inst✝² : AddCommMonoid E
inst✝¹ : TopologicalSpace E
inst✝ : SMul 𝕜 E
S T : ProperCone 𝕜 E
h : ↑S = ↑T
⊢ S = T

Next tactic:
cases S
theorem ext' : Function.Injective ((↑) : ProperCone 𝕜 E → ConvexCone 𝕜 E) := fun S T h => by
  cases S; 

Proof state:
case mk
𝕜 : Type u_1
inst✝³ : OrderedSemiring 𝕜
E : Type u_2
inst✝² : AddCommMonoid E
inst✝¹ : TopologicalSpace E
inst✝ : SMul 𝕜 E
T : ProperCone 𝕜 E
toConvexCone✝ : ConvexCone 𝕜 E
nonempty'✝ : Set.Nonempty toConvexCone✝.carrier
isClosed'✝ : IsClosed toConvexCone✝.carrier
h : ↑{ toConvexCone := toConvexCone✝, nonempty' := nonempty'✝, isClosed' := isClosed'✝ } = ↑T
⊢ { toConvexCone := toConvexCone✝, nonempty' := nonempty'✝, isClosed' := isClosed'✝ } = T

Next tactic:
cases T
theorem ext' : Function.Injective ((↑) : ProperCone 𝕜 E → ConvexCone 𝕜 E) := fun S T h => by
  cases S; cases T; 

Proof state:
case mk.mk
𝕜 : Type u_1
inst✝³ : OrderedSemiring 𝕜
E : Type u_2
inst✝² : AddCommMonoid E
inst✝¹ : TopologicalSpace E
inst✝ : SMul 𝕜 E
toConvexCone✝¹ : ConvexCone 𝕜 E
nonempty'✝¹ : Set.Nonempty toConvexCone✝¹.carrier
isClosed'✝¹ : IsClosed toConvexCone✝¹.carrier
toConvexCone✝ : ConvexCone 𝕜 E
nonempty'✝ : Set.Nonempty toConvexCone✝.carrier
isClosed'✝ : IsClosed toConvexCone✝.carrier
h :
  ↑{ toConvexCone := toConvexCone✝¹, nonempty' := nonempty'✝¹, isClosed' := isClosed'✝¹ } =
    ↑{ toConvexCone := toConvexCone✝, nonempty' := nonempty'✝, isClosed' := isClosed'✝ }
⊢ { toConvexCone := toConvexCone✝¹, nonempty' := nonempty'✝¹, isClosed' := isClosed'✝¹ } =
    { toConvexCone := toConvexCone✝, nonempty' := nonempty'✝, isClosed' := isClosed'✝ }

Next tactic:
congr
theorem pointed_zero : (0 : ProperCone 𝕜 E).Pointed := by 

Proof state:
𝕜 : Type u_1
inst✝⁴ : OrderedSemiring 𝕜
E : Type u_2
inst✝³ : AddCommMonoid E
inst✝² : TopologicalSpace E
inst✝¹ : T1Space E
inst✝ : Module 𝕜 E
⊢ ConvexCone.Pointed ↑0

Next tactic:
simp [ConvexCone.pointed_zero]
@[simp]
theorem map_id (K : ProperCone ℝ E) : K.map (ContinuousLinearMap.id ℝ E) = K :=
  ProperCone.ext' <| by 

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
K : ProperCone ℝ E
⊢ ↑(map (ContinuousLinearMap.id ℝ E) K) = ↑K

Next tactic:
simpa using IsClosed.closure_eq K.isClosed
@[simp]
theorem mem_dual {K : ProperCone ℝ E} {y : E} : y ∈ dual K ↔ ∀ ⦃x⦄, x ∈ K → 0 ≤ ⟪x, y⟫_ℝ := by
  

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
K : ProperCone ℝ E
y : E
⊢ y ∈ dual K ↔ ∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner x y

Next tactic:
rw [← mem_coe, coe_dual, mem_innerDualCone _ _]
@[simp]
theorem mem_dual {K : ProperCone ℝ E} {y : E} : y ∈ dual K ↔ ∀ ⦃x⦄, x ∈ K → 0 ≤ ⟪x, y⟫_ℝ := by
  rw [← mem_coe, coe_dual, mem_innerDualCone _ _]; 

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
K : ProperCone ℝ E
y : E
⊢ (∀ x ∈ ↑K, 0 ≤ inner x y) ↔ ∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner x y

Next tactic:
rfl
/-- The preimage of a proper cone under a continuous `ℝ`-linear map is a proper cone. -/
noncomputable def comap (f : E →L[ℝ] F) (S : ProperCone ℝ F) : ProperCone ℝ E where
  toConvexCone := ConvexCone.comap (f : E →ₗ[ℝ] F) S
  nonempty' :=
    ⟨0, by
      

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
f : E →L[ℝ] F
S : ProperCone ℝ F
⊢ 0 ∈ (ConvexCone.comap ↑f ↑S).carrier

Next tactic:
simp only [ConvexCone.comap, mem_preimage, map_zero, SetLike.mem_coe, mem_coe]
/-- The preimage of a proper cone under a continuous `ℝ`-linear map is a proper cone. -/
noncomputable def comap (f : E →L[ℝ] F) (S : ProperCone ℝ F) : ProperCone ℝ E where
  toConvexCone := ConvexCone.comap (f : E →ₗ[ℝ] F) S
  nonempty' :=
    ⟨0, by
      simp only [ConvexCone.comap, mem_preimage, map_zero, SetLike.mem_coe, mem_coe]
      

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
f : E →L[ℝ] F
S : ProperCone ℝ F
⊢ 0 ∈ S

Next tactic:
apply ProperCone.pointed
/-- The preimage of a proper cone under a continuous `ℝ`-linear map is a proper cone. -/
noncomputable def comap (f : E →L[ℝ] F) (S : ProperCone ℝ F) : ProperCone ℝ E where
  toConvexCone := ConvexCone.comap (f : E →ₗ[ℝ] F) S
  nonempty' :=
    ⟨0, by
      simp only [ConvexCone.comap, mem_preimage, map_zero, SetLike.mem_coe, mem_coe]
      apply ProperCone.pointed⟩
  isClosed' := by
    

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
f : E →L[ℝ] F
S : ProperCone ℝ F
⊢ IsClosed (ConvexCone.comap ↑f ↑S).carrier

Next tactic:
simp only [ConvexCone.comap, ContinuousLinearMap.coe_coe]
/-- The preimage of a proper cone under a continuous `ℝ`-linear map is a proper cone. -/
noncomputable def comap (f : E →L[ℝ] F) (S : ProperCone ℝ F) : ProperCone ℝ E where
  toConvexCone := ConvexCone.comap (f : E →ₗ[ℝ] F) S
  nonempty' :=
    ⟨0, by
      simp only [ConvexCone.comap, mem_preimage, map_zero, SetLike.mem_coe, mem_coe]
      apply ProperCone.pointed⟩
  isClosed' := by
    simp only [ConvexCone.comap, ContinuousLinearMap.coe_coe]
    

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
f : E →L[ℝ] F
S : ProperCone ℝ F
⊢ IsClosed (⇑f ⁻¹' ↑↑S)

Next tactic:
apply IsClosed.preimage f.2 S.isClosed
theorem comap_comap (g : F →L[ℝ] G) (f : E →L[ℝ] F) (S : ProperCone ℝ G) :
    (S.comap g).comap f = S.comap (g.comp f) :=
  SetLike.coe_injective <| by 

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
F : Type u_2
inst✝³ : NormedAddCommGroup F
inst✝² : InnerProductSpace ℝ F
G : Type u_3
inst✝¹ : NormedAddCommGroup G
inst✝ : InnerProductSpace ℝ G
g : F →L[ℝ] G
f : E →L[ℝ] F
S : ProperCone ℝ G
⊢ ↑(comap f (comap g S)) = ↑(comap (comp g f) S)

Next tactic:
congr
/-- This is a relative version of
`ConvexCone.hyperplane_separation_of_nonempty_of_isClosed_of_nmem`, which we recover by setting
`f` to be the identity map. This is a geometric interpretation of the Farkas' lemma
stated using proper cones. -/
theorem hyperplane_separation (K : ProperCone ℝ E) {f : E →L[ℝ] F} {b : F} :
    b ∈ K.map f ↔ ∀ y : F, adjoint f y ∈ K.dual → 0 ≤ ⟪y, b⟫_ℝ :=
  Iff.intro
    (by
      -- suppose `b ∈ K.map f`
      

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
inst✝³ : CompleteSpace E
F : Type u_2
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace ℝ F
inst✝ : CompleteSpace F
K : ProperCone ℝ E
f : E →L[ℝ] F
b : F
⊢ b ∈ map f K → ∀ (y : F), (adjoint f) y ∈ dual K → 0 ≤ inner y b

Next tactic:
simp only [ProperCone.mem_map, ProperCone.mem_dual, adjoint_inner_right,
        ConvexCone.mem_closure, mem_closure_iff_seq_limit]
/-- This is a relative version of
`ConvexCone.hyperplane_separation_of_nonempty_of_isClosed_of_nmem`, which we recover by setting
`f` to be the identity map. This is a geometric interpretation of the Farkas' lemma
stated using proper cones. -/
theorem hyperplane_separation (K : ProperCone ℝ E) {f : E →L[ℝ] F} {b : F} :
    b ∈ K.map f ↔ ∀ y : F, adjoint f y ∈ K.dual → 0 ≤ ⟪y, b⟫_ℝ :=
  Iff.intro
    (by
      -- suppose `b ∈ K.map f`
      simp only [ProperCone.mem_map, ProperCone.mem_dual, adjoint_inner_right,
        ConvexCone.mem_closure, mem_closure_iff_seq_limit]
      -- there is a sequence `seq : ℕ → F` in the image of `f` that converges to `b`
      

Proof state:
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
inst✝³ : CompleteSpace E
F : Type u_2
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace ℝ F
inst✝ : CompleteSpace F
K : ProperCone ℝ E
f : E →L[ℝ] F
b : F
⊢ (∃ x, (∀ (n : ℕ), x n ∈ ↑(ConvexCone.map ↑f ↑K)) ∧ Tendsto x atTop (nhds b)) →
    ∀ (y : F), (∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner (f x) y) → 0 ≤ inner y b

Next tactic:
rintro ⟨seq, hmem, htends⟩ y hinner
/-- This is a relative version of
`ConvexCone.hyperplane_separation_of_nonempty_of_isClosed_of_nmem`, which we recover by setting
`f` to be the identity map. This is a geometric interpretation of the Farkas' lemma
stated using proper cones. -/
theorem hyperplane_separation (K : ProperCone ℝ E) {f : E →L[ℝ] F} {b : F} :
    b ∈ K.map f ↔ ∀ y : F, adjoint f y ∈ K.dual → 0 ≤ ⟪y, b⟫_ℝ :=
  Iff.intro
    (by
      -- suppose `b ∈ K.map f`
      simp only [ProperCone.mem_map, ProperCone.mem_dual, adjoint_inner_right,
        ConvexCone.mem_closure, mem_closure_iff_seq_limit]
      -- there is a sequence `seq : ℕ → F` in the image of `f` that converges to `b`
      rintro ⟨seq, hmem, htends⟩ y hinner
      

Proof state:
case intro.intro
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
inst✝³ : CompleteSpace E
F : Type u_2
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace ℝ F
inst✝ : CompleteSpace F
K : ProperCone ℝ E
f : E →L[ℝ] F
b : F
seq : ℕ → F
hmem : ∀ (n : ℕ), seq n ∈ ↑(ConvexCone.map ↑f ↑K)
htends : Tendsto seq atTop (nhds b)
y : F
hinner : ∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner (f x) y
⊢ 0 ≤ inner y b

Next tactic:
suffices h : ∀ n, 0 ≤ ⟪y, seq n⟫_ℝ from
        ge_of_tendsto'
          (Continuous.seqContinuous (Continuous.inner (@continuous_const _ _ _ _ y) continuous_id)
            htends)
          h
/-- This is a relative version of
`ConvexCone.hyperplane_separation_of_nonempty_of_isClosed_of_nmem`, which we recover by setting
`f` to be the identity map. This is a geometric interpretation of the Farkas' lemma
stated using proper cones. -/
theorem hyperplane_separation (K : ProperCone ℝ E) {f : E →L[ℝ] F} {b : F} :
    b ∈ K.map f ↔ ∀ y : F, adjoint f y ∈ K.dual → 0 ≤ ⟪y, b⟫_ℝ :=
  Iff.intro
    (by
      -- suppose `b ∈ K.map f`
      simp only [ProperCone.mem_map, ProperCone.mem_dual, adjoint_inner_right,
        ConvexCone.mem_closure, mem_closure_iff_seq_limit]
      -- there is a sequence `seq : ℕ → F` in the image of `f` that converges to `b`
      rintro ⟨seq, hmem, htends⟩ y hinner
      suffices h : ∀ n, 0 ≤ ⟪y, seq n⟫_ℝ from
        ge_of_tendsto'
          (Continuous.seqContinuous (Continuous.inner (@continuous_const _ _ _ _ y) continuous_id)
            htends)
          h
      

Proof state:
case intro.intro
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
inst✝³ : CompleteSpace E
F : Type u_2
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace ℝ F
inst✝ : CompleteSpace F
K : ProperCone ℝ E
f : E →L[ℝ] F
b : F
seq : ℕ → F
hmem : ∀ (n : ℕ), seq n ∈ ↑(ConvexCone.map ↑f ↑K)
htends : Tendsto seq atTop (nhds b)
y : F
hinner : ∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner (f x) y
⊢ ∀ (n : ℕ), 0 ≤ inner y (seq n)

Next tactic:
intro n
/-- This is a relative version of
`ConvexCone.hyperplane_separation_of_nonempty_of_isClosed_of_nmem`, which we recover by setting
`f` to be the identity map. This is a geometric interpretation of the Farkas' lemma
stated using proper cones. -/
theorem hyperplane_separation (K : ProperCone ℝ E) {f : E →L[ℝ] F} {b : F} :
    b ∈ K.map f ↔ ∀ y : F, adjoint f y ∈ K.dual → 0 ≤ ⟪y, b⟫_ℝ :=
  Iff.intro
    (by
      -- suppose `b ∈ K.map f`
      simp only [ProperCone.mem_map, ProperCone.mem_dual, adjoint_inner_right,
        ConvexCone.mem_closure, mem_closure_iff_seq_limit]
      -- there is a sequence `seq : ℕ → F` in the image of `f` that converges to `b`
      rintro ⟨seq, hmem, htends⟩ y hinner
      suffices h : ∀ n, 0 ≤ ⟪y, seq n⟫_ℝ from
        ge_of_tendsto'
          (Continuous.seqContinuous (Continuous.inner (@continuous_const _ _ _ _ y) continuous_id)
            htends)
          h
      intro n
      

Proof state:
case intro.intro
E : Type u_1
inst✝⁵ : NormedAddCommGroup E
inst✝⁴ : InnerProductSpace ℝ E
inst✝³ : CompleteSpace E
F : Type u_2
inst✝² : NormedAddCommGroup F
inst✝¹ : InnerProductSpace ℝ F
inst✝ : CompleteSpace F
K : ProperCone ℝ E
f : E →L[ℝ] F
b : F
seq : ℕ → F
hmem : ∀ (n : ℕ), seq n ∈ ↑(ConvexCone.map ↑f ↑K)
htends : Tendsto seq atTop (nhds b)
y : F
hinner : ∀ ⦃x : E⦄, x ∈ K → 0 ≤ inner (f x) y
n : ℕ
⊢ 0 ≤ inner y (seq n)

Next tactic:
obtain ⟨_, h, hseq⟩ := hmem n