l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem edist_equiv_symm_fst (x₁ x₂ : α) :
    edist ((WithLp.equiv p (α × β)).symm (x₁, 0)) ((WithLp.equiv p (α × β)).symm (x₂, 0)) =
      edist x₁ x₂ := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : SeminormedAddCommGroup α
inst✝ : SeminormedAddCommGroup β
x₁ x₂ : α
⊢ edist ((WithLp.equiv p (α × β)).symm (x₁, 0)) ((WithLp.equiv p (α × β)).symm (x₂, 0)) = edist x₁ x₂

Next tactic:
simp only [edist_nndist, nndist_equiv_symm_fst p α β x₁ x₂]
@[simp]
theorem edist_equiv_symm_snd (y₁ y₂ : β) :
    edist ((WithLp.equiv p (α × β)).symm (0, y₁)) ((WithLp.equiv p (α × β)).symm (0, y₂)) =
      edist y₁ y₂ := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : SeminormedAddCommGroup α
inst✝ : SeminormedAddCommGroup β
y₁ y₂ : β
⊢ edist ((WithLp.equiv p (α × β)).symm (0, y₁)) ((WithLp.equiv p (α × β)).symm (0, y₂)) = edist y₁ y₂

Next tactic:
simp only [edist_nndist, nndist_equiv_symm_snd p α β y₁ y₂]
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
rcases p.dichotomy with (rfl | hp)
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · 

Proof state:
case inl
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
hp : Fact (1 ≤ ⊤)
f : WithLp ⊤ (α × β)
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      

Proof state:
case inl
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
hp : Fact (1 ≤ ⊤)
f : WithLp ⊤ (α × β)
⊢ ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊

Next tactic:
simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      

Proof state:
case inl
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
hp : Fact (1 ≤ ⊤)
f : WithLp ⊤ (α × β)
⊢ ‖(c • f).1‖₊ ⊔ ‖(c • f).2‖₊ = ‖c • f.1‖₊ ⊔ ‖c • f.2‖₊

Next tactic:
rfl
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · 

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
      

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
this : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
have smul_fst : (c • f).fst = c • f.fst := rfl
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
      have smul_fst : (c • f).fst = c • f.fst := rfl
      

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
this : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
smul_fst : (c • f).1 = c • f.1
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
have smul_snd : (c • f).snd = c • f.snd := rfl
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
      have smul_fst : (c • f).fst = c • f.fst := rfl
      have smul_snd : (c • f).snd = c • f.snd := rfl
      

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
this : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
smul_fst : (c • f).1 = c • f.1
smul_snd : (c • f).2 = c • f.2
⊢ ‖c • f‖ ≤ ‖c‖ * ‖f‖

Next tactic:
simp only [prod_norm_eq_add (zero_lt_one.trans_le hp), norm_smul, Real.mul_rpow,
        norm_nonneg, smul_fst, smul_snd]
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
      have smul_fst : (c • f).fst = c • f.fst := rfl
      have smul_snd : (c • f).snd = c • f.snd := rfl
      simp only [prod_norm_eq_add (zero_lt_one.trans_le hp), norm_smul, Real.mul_rpow,
        norm_nonneg, smul_fst, smul_snd]
      

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
this : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
smul_fst : (c • f).1 = c • f.1
smul_snd : (c • f).2 = c • f.2
⊢ (‖c‖ ^ ENNReal.toReal p * ‖f.1‖ ^ ENNReal.toReal p + ‖c‖ ^ ENNReal.toReal p * ‖f.2‖ ^ ENNReal.toReal p) ^
      (1 / ENNReal.toReal p) ≤
    ‖c‖ * (‖f.1‖ ^ ENNReal.toReal p + ‖f.2‖ ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p)

Next tactic:
rw [← mul_add, mul_rpow (rpow_nonneg_of_nonneg (norm_nonneg _) _),
        ← rpow_mul (norm_nonneg _), this, Real.rpow_one]
/-- The product of two normed spaces is a normed space, with the `L^p` norm. -/
instance instProdNormedSpace : NormedSpace 𝕜 (WithLp p (α × β)) where
  norm_smul_le c f := by
    rcases p.dichotomy with (rfl | hp)
    · suffices ‖c • f‖₊ = ‖c‖₊ * ‖f‖₊ from mod_cast NNReal.coe_mono this.le
      simp only [prod_nnnorm_eq_sup, NNReal.mul_sup, ← nnnorm_smul]
      rfl
    · have : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le hp).ne'
      have smul_fst : (c • f).fst = c • f.fst := rfl
      have smul_snd : (c • f).snd = c • f.snd := rfl
      simp only [prod_norm_eq_add (zero_lt_one.trans_le hp), norm_smul, Real.mul_rpow,
        norm_nonneg, smul_fst, smul_snd]
      rw [← mul_add, mul_rpow (rpow_nonneg_of_nonneg (norm_nonneg _) _),
        ← rpow_mul (norm_nonneg _), this, Real.rpow_one]
      

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp✝ : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
c : 𝕜
f : WithLp p (α × β)
hp : 1 ≤ ENNReal.toReal p
this : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
smul_fst : (c • f).1 = c • f.1
smul_snd : (c • f).2 = c • f.2
⊢ 0 ≤ ‖f.1‖ ^ ENNReal.toReal p + ‖f.2‖ ^ ENNReal.toReal p

Next tactic:
positivity
/-- The canonical map `WithLp.equiv` between `WithLp ∞ (α × β)` and `α × β` as a linear isometric
equivalence. -/
def prodEquivₗᵢ : WithLp ∞ (α × β) ≃ₗᵢ[𝕜] α × β where
  __ := WithLp.equiv ∞ (α × β)
  map_add' f g := rfl
  map_smul' c f := rfl
  norm_map' f := by 

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝⁴ : SeminormedAddCommGroup α
inst✝³ : SeminormedAddCommGroup β
inst✝² : NormedField 𝕜
inst✝¹ : NormedSpace 𝕜 α
inst✝ : NormedSpace 𝕜 β
src✝ : WithLp ⊤ (α × β) ≃ α × β := WithLp.equiv ⊤ (α × β)
f : WithLp ⊤ (α × β)
⊢ ‖{
          toLinearMap :=
            {
              toAddHom :=
                { toFun := src✝.toFun,
                  map_add' := (_ : ∀ (f g : WithLp ⊤ (α × β)), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ (f + g)) },
              map_smul' :=
                (_ :
                  ∀ (c : 𝕜) (f : WithLp ⊤ (α × β)),
                    AddHom.toFun
                        { toFun := src✝.toFun,
                          map_add' :=
                            (_ : ∀ (f g : WithLp ⊤ (α × β)), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ (f + g)) }
                        (c • f) =
                      AddHom.toFun
                        { toFun := src✝.toFun,
                          map_add' :=
                            (_ : ∀ (f g : WithLp ⊤ (α × β)), Equiv.toFun src✝ (f + g) = Equiv.toFun src✝ (f + g)) }
                        (c • f)) },
          invFun := src✝.invFun, left_inv := (_ : Function.LeftInverse src✝.invFun src✝.toFun),
          right_inv := (_ : Function.RightInverse src✝.invFun src✝.toFun) }
        f‖ =
    ‖f‖

Next tactic:
simp [Norm.norm]
theorem inv_inv : inv (inv r) = r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ inv (inv r) = r

Next tactic:
ext x y
theorem inv_inv : inv (inv r) = r := by
  ext x y
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x : α
y : β
⊢ inv (inv r) x y ↔ r x y

Next tactic:
rfl
theorem codom_inv : r.inv.codom = r.dom := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ codom (inv r) = dom r

Next tactic:
ext x
theorem codom_inv : r.inv.codom = r.dom := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x : α
⊢ x ∈ codom (inv r) ↔ x ∈ dom r

Next tactic:
rfl
theorem dom_inv : r.inv.dom = r.codom := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ dom (inv r) = codom r

Next tactic:
ext x
theorem dom_inv : r.inv.dom = r.codom := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x : β
⊢ x ∈ dom (inv r) ↔ x ∈ codom r

Next tactic:
rfl
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
⊢ (r • s) • t = r • s • t

Next tactic:
unfold comp
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
⊢ (fun x z => ∃ y, (∃ y_1, r x y_1 ∧ s y_1 y) ∧ t y z) = fun x z => ∃ y, r x y ∧ ∃ y_1, s y y_1 ∧ t y_1 z

Next tactic:
ext (x w)
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; ext (x w); 

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
x : α
w : δ
⊢ (∃ y, (∃ y_1, r x y_1 ∧ s y_1 y) ∧ t y w) ↔ ∃ y, r x y ∧ ∃ y_1, s y y_1 ∧ t y_1 w

Next tactic:
constructor
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; ext (x w); constructor
  · 

Proof state:
case a.h.a.mp
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
x : α
w : δ
⊢ (∃ y, (∃ y_1, r x y_1 ∧ s y_1 y) ∧ t y w) → ∃ y, r x y ∧ ∃ y_1, s y y_1 ∧ t y_1 w

Next tactic:
rintro ⟨z, ⟨y, rxy, syz⟩, tzw⟩
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; ext (x w); constructor
  · rintro ⟨z, ⟨y, rxy, syz⟩, tzw⟩; 

Proof state:
case a.h.a.mp.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
x : α
w : δ
z : γ
tzw : t z w
y : β
rxy : r x y
syz : s y z
⊢ ∃ y, r x y ∧ ∃ y_1, s y y_1 ∧ t y_1 w

Next tactic:
exact ⟨y, rxy, z, syz, tzw⟩
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; ext (x w); constructor
  · rintro ⟨z, ⟨y, rxy, syz⟩, tzw⟩; exact ⟨y, rxy, z, syz, tzw⟩
  · 

Proof state:
case a.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
x : α
w : δ
⊢ (∃ y, r x y ∧ ∃ y_1, s y y_1 ∧ t y_1 w) → ∃ y, (∃ y_1, r x y_1 ∧ s y_1 y) ∧ t y w

Next tactic:
rintro ⟨y, rxy, z, syz, tzw⟩
theorem comp_assoc (r : Rel α β) (s : Rel β γ) (t : Rel γ δ) : (r • s) • t = r • (s • t) := by
  unfold comp; ext (x w); constructor
  · rintro ⟨z, ⟨y, rxy, syz⟩, tzw⟩; exact ⟨y, rxy, z, syz, tzw⟩
  · rintro ⟨y, rxy, z, syz, tzw⟩; 

Proof state:
case a.h.a.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ : Rel α β
δ : Type u_4
r : Rel α β
s : Rel β γ
t : Rel γ δ
x : α
w : δ
y : β
rxy : r x y
z : γ
syz : s y z
tzw : t z w
⊢ ∃ y, (∃ y_1, r x y_1 ∧ s y_1 y) ∧ t y w

Next tactic:
exact ⟨z, ⟨y, rxy, syz⟩, tzw⟩
@[simp]
theorem comp_right_id (r : Rel α β) : r • @Eq β = r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ r • Eq = r

Next tactic:
unfold comp
@[simp]
theorem comp_right_id (r : Rel α β) : r • @Eq β = r := by
  unfold comp
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ (fun x z => ∃ y, r x y ∧ y = z) = r

Next tactic:
ext y
@[simp]
theorem comp_right_id (r : Rel α β) : r • @Eq β = r := by
  unfold comp
  ext y
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
y : α
x✝ : β
⊢ (∃ y_1, r y y_1 ∧ y_1 = x✝) ↔ r y x✝

Next tactic:
simp
@[simp]
theorem comp_left_id (r : Rel α β) : @Eq α • r = r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ Eq • r = r

Next tactic:
unfold comp
@[simp]
theorem comp_left_id (r : Rel α β) : @Eq α • r = r := by
  unfold comp
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ (fun x z => ∃ y, x = y ∧ r y z) = r

Next tactic:
ext x
@[simp]
theorem comp_left_id (r : Rel α β) : @Eq α • r = r := by
  unfold comp
  ext x
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
x : α
x✝ : β
⊢ (∃ y, x = y ∧ r y x✝) ↔ r x x✝

Next tactic:
simp
@[simp]
theorem comp_right_bot (r : Rel α β) : r • (⊥ : Rel β γ) = ⊥ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ r • ⊥ = ⊥

Next tactic:
ext x y
@[simp]
theorem comp_right_bot (r : Rel α β) : r • (⊥ : Rel β γ) = ⊥ := by
  ext x y
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
x : α
y : γ
⊢ (r • ⊥) x y ↔ ⊥ x y

Next tactic:
simp [comp, Bot.bot]
@[simp]
theorem comp_left_bot (r : Rel α β) : (⊥ : Rel γ α) • r = ⊥ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ ⊥ • r = ⊥

Next tactic:
ext x y
@[simp]
theorem comp_left_bot (r : Rel α β) : (⊥ : Rel γ α) • r = ⊥ := by
  ext x y
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
x : γ
y : β
⊢ (⊥ • r) x y ↔ ⊥ x y

Next tactic:
simp [comp, Bot.bot]
@[simp]
theorem comp_right_top (r : Rel α β) : r • (⊤ : Rel β γ) = λ x _ ↦ x ∈ r.dom := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ r • ⊤ = fun x x_1 => x ∈ dom r

Next tactic:
ext x z
@[simp]
theorem comp_right_top (r : Rel α β) : r • (⊤ : Rel β γ) = λ x _ ↦ x ∈ r.dom := by
  ext x z
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
x : α
z : γ
⊢ (r • ⊤) x z ↔ x ∈ dom r

Next tactic:
simp [comp, Top.top, dom]
@[simp]
theorem comp_left_top (r : Rel α β) : (⊤ : Rel γ α) • r = λ _ y ↦ y ∈ r.codom := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
⊢ ⊤ • r = fun x y => y ∈ codom r

Next tactic:
ext x z
@[simp]
theorem comp_left_top (r : Rel α β) : (⊤ : Rel γ α) • r = λ _ y ↦ y ∈ r.codom := by
  ext x z
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
x : γ
z : β
⊢ (⊤ • r) x z ↔ z ∈ codom r

Next tactic:
simp [comp, Top.top, codom]
theorem inv_id : inv (@Eq α) = @Eq α := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ inv Eq = Eq

Next tactic:
ext x y
theorem inv_id : inv (@Eq α) = @Eq α := by
  ext x y
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x y : α
⊢ inv Eq x y ↔ x = y

Next tactic:
constructor
theorem inv_id : inv (@Eq α) = @Eq α := by
  ext x y
  constructor <;> 

Proof state:
case a.h.a.mp
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x y : α
⊢ inv Eq x y → x = y

Next tactic:
apply Eq.symm
theorem inv_id : inv (@Eq α) = @Eq α := by
  ext x y
  constructor <;> 

Proof state:
case a.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x y : α
⊢ x = y → inv Eq x y

Next tactic:
apply Eq.symm
theorem inv_comp (r : Rel α β) (s : Rel β γ) : inv (r • s) = inv s • inv r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
s : Rel β γ
⊢ inv (r • s) = inv s • inv r

Next tactic:
ext x z
theorem inv_comp (r : Rel α β) (s : Rel β γ) : inv (r • s) = inv s • inv r := by
  ext x z
  

Proof state:
case a.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
r✝ r : Rel α β
s : Rel β γ
x : γ
z : α
⊢ inv (r • s) x z ↔ (inv s • inv r) x z

Next tactic:
simp [comp, inv, flip, and_comm]
@[simp]
theorem inv_bot : (⊥ : Rel α β).inv = (⊥ : Rel β α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ inv ⊥ = ⊥

Next tactic:
simp [Bot.bot, inv, flip]
@[simp]
theorem inv_top : (⊤ : Rel α β).inv = (⊤ : Rel β α) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ inv ⊤ = ⊤

Next tactic:
simp [Top.top, inv, flip]
@[simp]
theorem image_id (s : Set α) : image (@Eq α) s = s := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Set α
⊢ image Eq s = s

Next tactic:
ext x
@[simp]
theorem image_id (s : Set α) : image (@Eq α) s = s := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Set α
x : α
⊢ x ∈ image Eq s ↔ x ∈ s

Next tactic:
simp [mem_image]
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
⊢ image (r • s) t = image s (image r t)

Next tactic:
ext z
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
⊢ z ∈ image (r • s) t ↔ z ∈ image s (image r t)

Next tactic:
simp only [mem_image]
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; simp only [mem_image]; 

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
⊢ (∃ x ∈ t, (r • s) x z) ↔ ∃ x, (∃ x_1 ∈ t, r x_1 x) ∧ s x z

Next tactic:
constructor
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; simp only [mem_image]; constructor
  · 

Proof state:
case h.mp
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
⊢ (∃ x ∈ t, (r • s) x z) → ∃ x, (∃ x_1 ∈ t, r x_1 x) ∧ s x z

Next tactic:
rintro ⟨x, xt, y, rxy, syz⟩
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; simp only [mem_image]; constructor
  · rintro ⟨x, xt, y, rxy, syz⟩; 

Proof state:
case h.mp.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
x : α
xt : x ∈ t
y : β
rxy : r x y
syz : s y z
⊢ ∃ x, (∃ x_1 ∈ t, r x_1 x) ∧ s x z

Next tactic:
exact ⟨y, ⟨x, xt, rxy⟩, syz⟩
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; simp only [mem_image]; constructor
  · rintro ⟨x, xt, y, rxy, syz⟩; exact ⟨y, ⟨x, xt, rxy⟩, syz⟩
  · 

Proof state:
case h.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
⊢ (∃ x, (∃ x_1 ∈ t, r x_1 x) ∧ s x z) → ∃ x ∈ t, (r • s) x z

Next tactic:
rintro ⟨y, ⟨x, xt, rxy⟩, syz⟩
theorem image_comp (s : Rel β γ) (t : Set α) : image (r • s) t = image s (image r t) := by
  ext z; simp only [mem_image]; constructor
  · rintro ⟨x, xt, y, rxy, syz⟩; exact ⟨y, ⟨x, xt, rxy⟩, syz⟩
  · rintro ⟨y, ⟨x, xt, rxy⟩, syz⟩; 

Proof state:
case h.mpr.intro.intro.intro.intro
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Rel β γ
t : Set α
z : γ
y : β
syz : s y z
x : α
xt : x ∈ t
rxy : r x y
⊢ ∃ x ∈ t, (r • s) x z

Next tactic:
exact ⟨x, xt, y, rxy, syz⟩
theorem image_univ : r.image Set.univ = r.codom := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ image r Set.univ = codom r

Next tactic:
ext y
theorem image_univ : r.image Set.univ = r.codom := by
  ext y
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
y : β
⊢ y ∈ image r Set.univ ↔ y ∈ codom r

Next tactic:
simp [mem_image, codom]
@[simp]
theorem image_empty : r.image ∅ = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
⊢ image r ∅ = ∅

Next tactic:
ext x
@[simp]
theorem image_empty : r.image ∅ = ∅ := by
  ext x
  

Proof state:
case h
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
x : β
⊢ x ∈ image r ∅ ↔ x ∈ ∅

Next tactic:
simp [mem_image]
@[simp]
theorem image_bot (s : Set α) : (⊥ : Rel α β).image s = ∅ := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Set α
⊢ image ⊥ s = ∅

Next tactic:
rw [Set.eq_empty_iff_forall_not_mem]
@[simp]
theorem image_bot (s : Set α) : (⊥ : Rel α β).image s = ∅ := by
  rw [Set.eq_empty_iff_forall_not_mem]
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
r : Rel α β
s : Set α
⊢ ∀ (x : β), x ∉ image ⊥ s

Next tactic:
intro x h