l3lab/ntp-mathlib huggingface dataset:
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · 

Proof state:
case refine_3
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
⊢ IsBoundedUnder (fun x x_1 => x ≥ x_1) atTop fun x => (fun s => ENNReal.toNNReal (↑↑↑(μs x) s)) G

Next tactic:
use 0
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · use 0
      

Proof state:
case h
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
⊢ ∀ᶠ (x : ℝ≥0) in map (fun x => (fun s => ENNReal.toNNReal (↑↑↑(μs x) s)) G) atTop, (fun x x_1 => x ≥ x_1) x 0

Next tactic:
simp only [zero_le, eventually_map, eventually_atTop, ge_iff_le, implies_true, forall_const,
        exists_const]
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · use 0
      simp only [zero_le, eventually_map, eventually_atTop, ge_iff_le, implies_true, forall_const,
        exists_const]
  

Proof state:
case h
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
aux :
  ↑(liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop) =
    liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
⊢ ↑↑↑μ G ≤ liminf (fun i => ↑↑↑(μs i) G) atTop

Next tactic:
have obs := ENNReal.coe_mono h_opens
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · use 0
      simp only [zero_le, eventually_map, eventually_atTop, ge_iff_le, implies_true, forall_const,
        exists_const]
  have obs := ENNReal.coe_mono h_opens
  

Proof state:
case h
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
aux :
  ↑(liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop) =
    liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
obs : ↑(ENNReal.toNNReal (↑↑↑μ G)) ≤ ↑(liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop)
⊢ ↑↑↑μ G ≤ liminf (fun i => ↑↑↑(μs i) G) atTop

Next tactic:
simp only [ne_eq, ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure, aux] at obs
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · use 0
      simp only [zero_le, eventually_map, eventually_atTop, ge_iff_le, implies_true, forall_const,
        exists_const]
  have obs := ENNReal.coe_mono h_opens
  simp only [ne_eq, ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure, aux] at obs
  

Proof state:
case h
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
aux :
  ↑(liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop) =
    liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
obs : ↑↑↑μ G ≤ liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
⊢ ↑↑↑μ G ≤ liminf (fun i => ↑↑↑(μs i) G) atTop

Next tactic:
convert obs
/-- One implication of the portmanteau theorem:
If for all open sets G we have the liminf condition `μ(G) ≤ liminf μsₙ(G)`, then the measures
μsₙ converge weakly to the measure μ. -/
theorem tendsto_of_forall_isOpen_le_liminf {μ : ProbabilityMeasure Ω}
    {μs : ℕ → ProbabilityMeasure Ω}
    (h_opens : ∀ G, IsOpen G → μ G ≤ atTop.liminf (fun i ↦ μs i G)) :
    atTop.Tendsto (fun i ↦ μs i) (𝓝 μ) := by
  refine ProbabilityMeasure.tendsto_iff_forall_integral_tendsto.mpr ?_
  apply tendsto_integral_of_forall_integral_le_liminf_integral
  intro f f_nn
  apply integral_le_liminf_integral_of_forall_isOpen_measure_le_liminf_measure (f := f) f_nn
  intro G G_open
  specialize h_opens G G_open
  simp only at h_opens
  have aux : ENNReal.ofNNReal (liminf (fun i ↦ ENNReal.toNNReal ((μs i : Measure Ω) G)) atTop) =
          liminf (ENNReal.ofNNReal ∘ fun i ↦ (ENNReal.toNNReal ((μs i : Measure Ω) G))) atTop := by
    refine Monotone.map_liminf_of_continuousAt (F := atTop) ENNReal.coe_mono (μs · G) ?_ ?_ ?_
    · apply ENNReal.continuous_coe.continuousAt
    · use 1
      simp only [eventually_map, ProbabilityMeasure.apply_le_one, eventually_atTop, ge_iff_le,
        implies_true, forall_const, exists_const]
    · use 0
      simp only [zero_le, eventually_map, eventually_atTop, ge_iff_le, implies_true, forall_const,
        exists_const]
  have obs := ENNReal.coe_mono h_opens
  simp only [ne_eq, ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure, aux] at obs
  convert obs
  

Proof state:
case h.e'_4.h.e'_4.h
Ω : Type u_1
inst✝² : MeasurableSpace Ω
inst✝¹ : TopologicalSpace Ω
inst✝ : OpensMeasurableSpace Ω
μ : ProbabilityMeasure Ω
μs : ℕ → ProbabilityMeasure Ω
f : Ω →ᵇ ℝ
f_nn : 0 ≤ f
G : Set Ω
G_open : IsOpen G
h_opens : ENNReal.toNNReal (↑↑↑μ G) ≤ liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
aux :
  ↑(liminf (fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop) =
    liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
obs : ↑↑↑μ G ≤ liminf (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) atTop
x✝ : ℕ
⊢ ↑↑↑(μs x✝) G = (ENNReal.ofNNReal ∘ fun i => ENNReal.toNNReal (↑↑↑(μs i) G)) x✝

Next tactic:
simp only [Function.comp_apply, ne_eq, ProbabilityMeasure.ennreal_coeFn_eq_coeFn_toMeasure]
instance (X : C) : PartialOrder (Subobject X) := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
⊢ PartialOrder (Subobject X)

Next tactic:
dsimp only [Subobject]
instance (X : C) : PartialOrder (Subobject X) := by
  dsimp only [Subobject]
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
⊢ PartialOrder (ThinSkeleton (MonoOver X))

Next tactic:
infer_instance
protected theorem ind {X : C} (p : Subobject X → Prop)
    (h : ∀ ⦃A : C⦄ (f : A ⟶ X) [Mono f], p (Subobject.mk f)) (P : Subobject X) : p P := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Prop
h : ∀ ⦃A : C⦄ (f : A ⟶ X) [inst : Mono f], p (mk f)
P : Subobject X
⊢ p P

Next tactic:
apply Quotient.inductionOn'
protected theorem ind {X : C} (p : Subobject X → Prop)
    (h : ∀ ⦃A : C⦄ (f : A ⟶ X) [Mono f], p (Subobject.mk f)) (P : Subobject X) : p P := by
  apply Quotient.inductionOn'
  

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Prop
h : ∀ ⦃A : C⦄ (f : A ⟶ X) [inst : Mono f], p (mk f)
P : Subobject X
⊢ ∀ (a : MonoOver X), p (Quotient.mk'' a)

Next tactic:
intro a
protected theorem ind {X : C} (p : Subobject X → Prop)
    (h : ∀ ⦃A : C⦄ (f : A ⟶ X) [Mono f], p (Subobject.mk f)) (P : Subobject X) : p P := by
  apply Quotient.inductionOn'
  intro a
  

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Prop
h : ∀ ⦃A : C⦄ (f : A ⟶ X) [inst : Mono f], p (mk f)
P : Subobject X
a : MonoOver X
⊢ p (Quotient.mk'' a)

Next tactic:
exact h a.arrow
protected theorem ind₂ {X : C} (p : Subobject X → Subobject X → Prop)
    (h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [Mono f] [Mono g],
      p (Subobject.mk f) (Subobject.mk g))
    (P Q : Subobject X) : p P Q := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Subobject X → Prop
h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g], p (mk f) (mk g)
P Q : Subobject X
⊢ p P Q

Next tactic:
apply Quotient.inductionOn₂'
protected theorem ind₂ {X : C} (p : Subobject X → Subobject X → Prop)
    (h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [Mono f] [Mono g],
      p (Subobject.mk f) (Subobject.mk g))
    (P Q : Subobject X) : p P Q := by
  apply Quotient.inductionOn₂'
  

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Subobject X → Prop
h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g], p (mk f) (mk g)
P Q : Subobject X
⊢ ∀ (a₁ a₂ : MonoOver X), p (Quotient.mk'' a₁) (Quotient.mk'' a₂)

Next tactic:
intro a b
protected theorem ind₂ {X : C} (p : Subobject X → Subobject X → Prop)
    (h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [Mono f] [Mono g],
      p (Subobject.mk f) (Subobject.mk g))
    (P Q : Subobject X) : p P Q := by
  apply Quotient.inductionOn₂'
  intro a b
  

Proof state:
case h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
X : C
p : Subobject X → Subobject X → Prop
h : ∀ ⦃A B : C⦄ (f : A ⟶ X) (g : B ⟶ X) [inst : Mono f] [inst_1 : Mono g], p (mk f) (mk g)
P Q : Subobject X
a b : MonoOver X
⊢ p (Quotient.mk'' a) (Quotient.mk'' b)

Next tactic:
exact h a.arrow b.arrow
@[simp]
theorem arrow_congr {A : C} (X Y : Subobject A) (h : X = Y) :
    eqToHom (congr_arg (fun X : Subobject A => (X : C)) h) ≫ Y.arrow = X.arrow := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
A : C
X Y : Subobject A
h : X = Y
⊢ eqToHom (_ : underlying.obj X = underlying.obj Y) ≫ arrow Y = arrow X

Next tactic:
induction h
@[simp]
theorem arrow_congr {A : C} (X Y : Subobject A) (h : X = Y) :
    eqToHom (congr_arg (fun X : Subobject A => (X : C)) h) ≫ Y.arrow = X.arrow := by
  induction h
  

Proof state:
case refl
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
A : C
X Y : Subobject A
⊢ eqToHom (_ : underlying.obj X = underlying.obj X) ≫ arrow X = arrow X

Next tactic:
simp
@[simp]
theorem mk_arrow (P : Subobject X) : mk P.arrow = P :=
  Quotient.inductionOn' P fun Q => by
    

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
P : Subobject X
Q : MonoOver X
⊢ mk (arrow (Quotient.mk'' Q)) = Quotient.mk'' Q

Next tactic:
obtain ⟨e⟩ := @Quotient.mk_out' _ (isIsomorphicSetoid _) Q
@[simp]
theorem mk_arrow (P : Subobject X) : mk P.arrow = P :=
  Quotient.inductionOn' P fun Q => by
    obtain ⟨e⟩ := @Quotient.mk_out' _ (isIsomorphicSetoid _) Q
    

Proof state:
case intro
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X Y Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
P : Subobject X
Q : MonoOver X
e : Quotient.out' (Quotient.mk'' Q) ≅ Q
⊢ mk (arrow (Quotient.mk'' Q)) = Quotient.mk'' Q

Next tactic:
exact Quotient.sound' ⟨MonoOver.isoMk (Iso.refl _) ≪≫ e⟩
theorem le_of_comm {B : C} {X Y : Subobject B} (f : (X : C) ⟶ (Y : C)) (w : f ≫ Y.arrow = X.arrow) :
    X ≤ Y := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
f : underlying.obj X ⟶ underlying.obj Y
w : f ≫ arrow Y = arrow X
⊢ X ≤ Y

Next tactic:
convert mk_le_mk_of_comm _ w
theorem le_of_comm {B : C} {X Y : Subobject B} (f : (X : C) ⟶ (Y : C)) (w : f ≫ Y.arrow = X.arrow) :
    X ≤ Y := by
  convert mk_le_mk_of_comm _ w <;> 

Proof state:
case h.e'_3
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
f : underlying.obj X ⟶ underlying.obj Y
w : f ≫ arrow Y = arrow X
⊢ X = mk (arrow X)

Next tactic:
simp
theorem le_of_comm {B : C} {X Y : Subobject B} (f : (X : C) ⟶ (Y : C)) (w : f ≫ Y.arrow = X.arrow) :
    X ≤ Y := by
  convert mk_le_mk_of_comm _ w <;> 

Proof state:
case h.e'_4
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
f : underlying.obj X ⟶ underlying.obj Y
w : f ≫ arrow Y = arrow X
⊢ Y = mk (arrow Y)

Next tactic:
simp
theorem le_mk_of_comm {B A : C} {X : Subobject B} {f : A ⟶ B} [Mono f] (g : (X : C) ⟶ A)
    (w : g ≫ f = X.arrow) : X ≤ mk f :=
  le_of_comm (g ≫ (underlyingIso f).inv) <| by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
B A : C
X : Subobject B
f : A ⟶ B
inst✝ : Mono f
g : underlying.obj X ⟶ A
w : g ≫ f = arrow X
⊢ (g ≫ (underlyingIso f).inv) ≫ arrow (mk f) = arrow X

Next tactic:
simp [w]
theorem mk_le_of_comm {B A : C} {X : Subobject B} {f : A ⟶ B} [Mono f] (g : A ⟶ (X : C))
    (w : g ≫ X.arrow = f) : mk f ≤ X :=
  le_of_comm ((underlyingIso f).hom ≫ g) <| by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
B A : C
X : Subobject B
f : A ⟶ B
inst✝ : Mono f
g : A ⟶ underlying.obj X
w : g ≫ arrow X = f
⊢ ((underlyingIso f).hom ≫ g) ≫ arrow X = arrow (mk f)

Next tactic:
simp [w]
/-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with
    the arrows. -/
theorem eq_mk_of_comm {B A : C} {X : Subobject B} (f : A ⟶ B) [Mono f] (i : (X : C) ≅ A)
    (w : i.hom ≫ f = X.arrow) : X = mk f :=
  eq_of_comm (i.trans (underlyingIso f).symm) <| by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
B A : C
X : Subobject B
f : A ⟶ B
inst✝ : Mono f
i : underlying.obj X ≅ A
w : i.hom ≫ f = arrow X
⊢ (i ≪≫ (underlyingIso f).symm).hom ≫ arrow (mk f) = arrow X

Next tactic:
simp [w]
/-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with
    the arrows. -/
theorem mk_eq_of_comm {B A : C} {X : Subobject B} (f : A ⟶ B) [Mono f] (i : A ≅ (X : C))
    (w : i.hom ≫ X.arrow = f) : mk f = X :=
  Eq.symm <| eq_mk_of_comm _ i.symm <| by 

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
B A : C
X : Subobject B
f : A ⟶ B
inst✝ : Mono f
i : A ≅ underlying.obj X
w : i.hom ≫ arrow X = f
⊢ i.symm.hom ≫ f = arrow X

Next tactic:
rw [Iso.symm_hom, Iso.inv_comp_eq, w]
/-- To show that two subobjects are equal, it suffices to exhibit an isomorphism commuting with
    the arrows. -/
theorem mk_eq_mk_of_comm {B A₁ A₂ : C} (f : A₁ ⟶ B) (g : A₂ ⟶ B) [Mono f] [Mono g] (i : A₁ ≅ A₂)
    (w : i.hom ≫ g = f) : mk f = mk g :=
  eq_mk_of_comm _ ((underlyingIso f).trans i) <| by 

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
X Y Z : C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
B A₁ A₂ : C
f : A₁ ⟶ B
g : A₂ ⟶ B
inst✝¹ : Mono f
inst✝ : Mono g
i : A₁ ≅ A₂
w : i.hom ≫ g = f
⊢ (underlyingIso f ≪≫ i).hom ≫ g = arrow (mk f)

Next tactic:
simp [w]
instance {B : C} (X Y : Subobject B) (h : X ≤ Y) : Mono (ofLE X Y h) := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
h : X ≤ Y
⊢ Mono (ofLE X Y h)

Next tactic:
fconstructor
instance {B : C} (X Y : Subobject B) (h : X ≤ Y) : Mono (ofLE X Y h) := by
  fconstructor
  

Proof state:
case right_cancellation
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
h : X ≤ Y
⊢ ∀ {Z : C} (g h_1 : Z ⟶ underlying.obj X), g ≫ ofLE X Y h = h_1 ≫ ofLE X Y h → g = h_1

Next tactic:
intro Z f g w
instance {B : C} (X Y : Subobject B) (h : X ≤ Y) : Mono (ofLE X Y h) := by
  fconstructor
  intro Z f g w
  

Proof state:
case right_cancellation
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z✝ : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
h : X ≤ Y
Z : C
f g : Z ⟶ underlying.obj X
w : f ≫ ofLE X Y h = g ≫ ofLE X Y h
⊢ f = g

Next tactic:
replace w := w =≫ Y.arrow
instance {B : C} (X Y : Subobject B) (h : X ≤ Y) : Mono (ofLE X Y h) := by
  fconstructor
  intro Z f g w
  replace w := w =≫ Y.arrow
  

Proof state:
case right_cancellation
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z✝ : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
h : X ≤ Y
Z : C
f g : Z ⟶ underlying.obj X
w : (f ≫ ofLE X Y h) ≫ arrow Y = (g ≫ ofLE X Y h) ≫ arrow Y
⊢ f = g

Next tactic:
ext
instance {B : C} (X Y : Subobject B) (h : X ≤ Y) : Mono (ofLE X Y h) := by
  fconstructor
  intro Z f g w
  replace w := w =≫ Y.arrow
  ext
  

Proof state:
case right_cancellation.h
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
X✝ Y✝ Z✝ : C
D : Type u₂
inst✝ : Category.{v₂, u₂} D
B : C
X Y : Subobject B
h : X ≤ Y
Z : C
f g : Z ⟶ underlying.obj X
w : (f ≫ ofLE X Y h) ≫ arrow Y = (g ≫ ofLE X Y h) ≫ arrow Y
⊢ f ≫ arrow X = g ≫ arrow X

Next tactic:
simpa using w
theorem ofLE_mk_le_mk_of_comm {B A₁ A₂ : C} {f₁ : A₁ ⟶ B} {f₂ : A₂ ⟶ B} [Mono f₁] [Mono f₂]
    (g : A₁ ⟶ A₂) (w : g ≫ f₂ = f₁) :
    ofLE _ _ (mk_le_mk_of_comm g w) = (underlyingIso _).hom ≫ g ≫ (underlyingIso _).inv := by
  

Proof state:
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
X Y Z : C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
B A₁ A₂ : C
f₁ : A₁ ⟶ B
f₂ : A₂ ⟶ B
inst✝¹ : Mono f₁
inst✝ : Mono f₂
g : A₁ ⟶ A₂
w : g ≫ f₂ = f₁
⊢ ofLE (mk f₁) (mk f₂) (_ : mk f₁ ≤ mk f₂) = (underlyingIso f₁).hom ≫ g ≫ (underlyingIso f₂).inv

Next tactic:
ext
theorem ofLE_mk_le_mk_of_comm {B A₁ A₂ : C} {f₁ : A₁ ⟶ B} {f₂ : A₂ ⟶ B} [Mono f₁] [Mono f₂]
    (g : A₁ ⟶ A₂) (w : g ≫ f₂ = f₁) :
    ofLE _ _ (mk_le_mk_of_comm g w) = (underlyingIso _).hom ≫ g ≫ (underlyingIso _).inv := by
  ext
  

Proof state:
case h
C : Type u₁
inst✝³ : Category.{v₁, u₁} C
X Y Z : C
D : Type u₂
inst✝² : Category.{v₂, u₂} D
B A₁ A₂ : C
f₁ : A₁ ⟶ B
f₂ : A₂ ⟶ B
inst✝¹ : Mono f₁
inst✝ : Mono f₂
g : A₁ ⟶ A₂
w : g ≫ f₂ = f₁
⊢ ofLE (mk f₁) (mk f₂) (_ : mk f₁ ≤ mk f₂) ≫ arrow (mk f₂) =
    ((underlyingIso f₁).hom ≫ g ≫ (underlyingIso f₂).inv) ≫ arrow (mk f₂)

Next tactic:
simp [w]
instance {B A : C} (X : Subobject B) (f : A ⟶ B) [Mono f] (h : X ≤ mk f) :
    Mono (ofLEMk X f h) := by
  

Proof state:
C : Type u₁
inst✝² : Category.{v₁, u₁} C
X✝ Y Z : C
D : Type u₂
inst✝¹ : Category.{v₂, u₂} D
B A : C
X : Subobject B
f : A ⟶ B
inst✝ : Mono f
h : X ≤ mk f
⊢ Mono (ofLEMk X f h)

Next tactic:
dsimp only [ofLEMk]