l3lab/ntp-mathlib huggingface dataset:
theorem entry_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜)
    (i j : n) : ‖U i j‖ ≤ 1 := by
  -- The norm squared of an entry is at most the L2 norm of its row.
  have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 := by
    apply Multiset.single_le_sum
    · intro x h_x
      rw [Multiset.mem_map] at h_x
      cases' h_x with a h_a
      rw [← h_a.2]
      apply sq_nonneg
    · rw [Multiset.mem_map]
      use j
      simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ
  have diag_eq_norm_sum : (U * Uᴴ) i i = (∑ x : n, ‖U i x‖ ^ 2 : ℝ) := by
    simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj,
      IsROrC.normSq_eq_def', IsROrC.ofReal_pow]; norm_cast
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
  have re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 := by
    rw [IsROrC.ext_iff] at diag_eq_norm_sum
    rw [diag_eq_norm_sum.1]
    norm_cast
  -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
  have mul_eq_one : U * Uᴴ = 1 := unitary.mul_star_self_of_mem hU
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
⊢ ‖U i j‖ ≤ 1

Next tactic:
have diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1 := by
    simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
theorem entry_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜)
    (i j : n) : ‖U i j‖ ≤ 1 := by
  -- The norm squared of an entry is at most the L2 norm of its row.
  have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 := by
    apply Multiset.single_le_sum
    · intro x h_x
      rw [Multiset.mem_map] at h_x
      cases' h_x with a h_a
      rw [← h_a.2]
      apply sq_nonneg
    · rw [Multiset.mem_map]
      use j
      simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ
  have diag_eq_norm_sum : (U * Uᴴ) i i = (∑ x : n, ‖U i x‖ ^ 2 : ℝ) := by
    simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj,
      IsROrC.normSq_eq_def', IsROrC.ofReal_pow]; norm_cast
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
  have re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 := by
    rw [IsROrC.ext_iff] at diag_eq_norm_sum
    rw [diag_eq_norm_sum.1]
    norm_cast
  -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
  have mul_eq_one : U * Uᴴ = 1 := unitary.mul_star_self_of_mem hU
  have diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1 := by
    

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
⊢ IsROrC.re ((U * Uᴴ) i i) = 1

Next tactic:
simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
theorem entry_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜)
    (i j : n) : ‖U i j‖ ≤ 1 := by
  -- The norm squared of an entry is at most the L2 norm of its row.
  have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 := by
    apply Multiset.single_le_sum
    · intro x h_x
      rw [Multiset.mem_map] at h_x
      cases' h_x with a h_a
      rw [← h_a.2]
      apply sq_nonneg
    · rw [Multiset.mem_map]
      use j
      simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ
  have diag_eq_norm_sum : (U * Uᴴ) i i = (∑ x : n, ‖U i x‖ ^ 2 : ℝ) := by
    simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj,
      IsROrC.normSq_eq_def', IsROrC.ofReal_pow]; norm_cast
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
  have re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 := by
    rw [IsROrC.ext_iff] at diag_eq_norm_sum
    rw [diag_eq_norm_sum.1]
    norm_cast
  -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
  have mul_eq_one : U * Uᴴ = 1 := unitary.mul_star_self_of_mem hU
  have diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1 := by
    simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
  -- Putting it all together
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1
⊢ ‖U i j‖ ≤ 1

Next tactic:
rw [← sq_le_one_iff (norm_nonneg (U i j)), ← diag_eq_one, re_diag_eq_norm_sum]
theorem entry_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜)
    (i j : n) : ‖U i j‖ ≤ 1 := by
  -- The norm squared of an entry is at most the L2 norm of its row.
  have norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x, ‖U i x‖ ^ 2 := by
    apply Multiset.single_le_sum
    · intro x h_x
      rw [Multiset.mem_map] at h_x
      cases' h_x with a h_a
      rw [← h_a.2]
      apply sq_nonneg
    · rw [Multiset.mem_map]
      use j
      simp only [eq_self_iff_true, Finset.mem_univ_val, and_self_iff, sq_eq_sq]
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ
  have diag_eq_norm_sum : (U * Uᴴ) i i = (∑ x : n, ‖U i x‖ ^ 2 : ℝ) := by
    simp only [Matrix.mul_apply, Matrix.conjTranspose_apply, ← starRingEnd_apply, IsROrC.mul_conj,
      IsROrC.normSq_eq_def', IsROrC.ofReal_pow]; norm_cast
  -- The L2 norm of a row is a diagonal entry of U * Uᴴ, real part
  have re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2 := by
    rw [IsROrC.ext_iff] at diag_eq_norm_sum
    rw [diag_eq_norm_sum.1]
    norm_cast
  -- Since U is unitary, the diagonal entries of U * Uᴴ are all 1
  have mul_eq_one : U * Uᴴ = 1 := unitary.mul_star_self_of_mem hU
  have diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1 := by
    simp only [mul_eq_one, eq_self_iff_true, Matrix.one_apply_eq, IsROrC.one_re]
  -- Putting it all together
  rw [← sq_le_one_iff (norm_nonneg (U i j)), ← diag_eq_one, re_diag_eq_norm_sum]
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i j : n
norm_sum : ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2
diag_eq_norm_sum : (U * Uᴴ) i i = ↑(∑ x : n, ‖U i x‖ ^ 2)
re_diag_eq_norm_sum : IsROrC.re ((U * Uᴴ) i i) = ∑ x : n, ‖U i x‖ ^ 2
mul_eq_one : U * Uᴴ = 1
diag_eq_one : IsROrC.re ((U * Uᴴ) i i) = 1
⊢ ‖U i j‖ ^ 2 ≤ ∑ x : n, ‖U i x‖ ^ 2

Next tactic:
exact norm_sum
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
⊢ ‖U‖ ≤ 1

Next tactic:
conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
    intro
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ‖U‖ ≤ 1

Next tactic:
rw [pi_norm_le_iff_of_nonneg zero_le_one]
    intro
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ‖U‖ ≤ 1

Next tactic:
rw [pi_norm_le_iff_of_nonneg zero_le_one]
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
    

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
| ∀ (i : n), ‖U i‖ ≤ 1

Next tactic:
intro
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
    intro
    

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i✝ : n
| ‖U i✝‖ ≤ 1

Next tactic:
rw [pi_norm_le_iff_of_nonneg zero_le_one]
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
    intro
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
⊢ ∀ (i i_1 : n), ‖U i i_1‖ ≤ 1

Next tactic:
intros
/-- The entrywise sup norm of a unitary matrix is at most 1. -/
theorem entrywise_sup_norm_bound_of_unitary {U : Matrix n n 𝕜} (hU : U ∈ Matrix.unitaryGroup n 𝕜) :
    ‖U‖ ≤ 1 := by
  conv => -- Porting note: was `simp_rw [pi_norm_le_iff_of_nonneg zero_le_one]`
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
    intro
    rw [pi_norm_le_iff_of_nonneg zero_le_one]
  intros
  

Proof state:
𝕜 : Type u_1
m : Type u_2
n : Type u_3
E : Type u_4
inst✝² : IsROrC 𝕜
inst✝¹ : Fintype n
inst✝ : DecidableEq n
U : Matrix n n 𝕜
hU : U ∈ Matrix.unitaryGroup n 𝕜
i✝¹ i✝ : n
⊢ ‖U i✝¹ i✝‖ ≤ 1

Next tactic:
exact entry_norm_bound_of_unitary hU _ _
theorem AddHom.le_map_tsub [Preorder β] [Add β] [Sub β] [OrderedSub β] (f : AddHom α β)
    (hf : Monotone f) (a b : α) : f a - f b ≤ f (a - b) := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝⁷ : Preorder α
inst✝⁶ : Add α
inst✝⁵ : Sub α
inst✝⁴ : OrderedSub α
a✝ b✝ c d : α
inst✝³ : Preorder β
inst✝² : Add β
inst✝¹ : Sub β
inst✝ : OrderedSub β
f : AddHom α β
hf : Monotone ⇑f
a b : α
⊢ f a - f b ≤ f (a - b)

Next tactic:
rw [tsub_le_iff_right, ← f.map_add]
theorem AddHom.le_map_tsub [Preorder β] [Add β] [Sub β] [OrderedSub β] (f : AddHom α β)
    (hf : Monotone f) (a b : α) : f a - f b ≤ f (a - b) := by
  rw [tsub_le_iff_right, ← f.map_add]
  

Proof state:
α : Type u_1
β : Type u_2
inst✝⁷ : Preorder α
inst✝⁶ : Add α
inst✝⁵ : Sub α
inst✝⁴ : OrderedSub α
a✝ b✝ c d : α
inst✝³ : Preorder β
inst✝² : Add β
inst✝¹ : Sub β
inst✝ : OrderedSub β
f : AddHom α β
hf : Monotone ⇑f
a b : α
⊢ f a ≤ f (a - b + b)

Next tactic:
exact hf le_tsub_add
theorem le_tsub_mul {R : Type*} [CommSemiring R] [Preorder R] [Sub R] [OrderedSub R]
    [CovariantClass R R (· * ·) (· ≤ ·)] {a b c : R} : a * c - b * c ≤ (a - b) * c := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝⁸ : Preorder α
inst✝⁷ : Add α
inst✝⁶ : Sub α
inst✝⁵ : OrderedSub α
a✝ b✝ c✝ d : α
R : Type u_3
inst✝⁴ : CommSemiring R
inst✝³ : Preorder R
inst✝² : Sub R
inst✝¹ : OrderedSub R
inst✝ : CovariantClass R R (fun x x_1 => x * x_1) fun x x_1 => x ≤ x_1
a b c : R
⊢ a * c - b * c ≤ (a - b) * c

Next tactic:
simpa only [mul_comm _ c] using le_mul_tsub
/-- An order isomorphism between types with ordered subtraction preserves subtraction provided that
it preserves addition. -/
theorem OrderIso.map_tsub {M N : Type*} [Preorder M] [Add M] [Sub M] [OrderedSub M]
    [PartialOrder N] [Add N] [Sub N] [OrderedSub N] (e : M ≃o N)
    (h_add : ∀ a b, e (a + b) = e a + e b) (a b : M) : e (a - b) = e a - e b := by
  

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
N : Type u_4
inst✝⁷ : Preorder M
inst✝⁶ : Add M
inst✝⁵ : Sub M
inst✝⁴ : OrderedSub M
inst✝³ : PartialOrder N
inst✝² : Add N
inst✝¹ : Sub N
inst✝ : OrderedSub N
e : M ≃o N
h_add : ∀ (a b : M), e (a + b) = e a + e b
a b : M
⊢ e (a - b) = e a - e b

Next tactic:
let e_add : M ≃+ N := { e with map_add' := h_add }
/-- An order isomorphism between types with ordered subtraction preserves subtraction provided that
it preserves addition. -/
theorem OrderIso.map_tsub {M N : Type*} [Preorder M] [Add M] [Sub M] [OrderedSub M]
    [PartialOrder N] [Add N] [Sub N] [OrderedSub N] (e : M ≃o N)
    (h_add : ∀ a b, e (a + b) = e a + e b) (a b : M) : e (a - b) = e a - e b := by
  let e_add : M ≃+ N := { e with map_add' := h_add }
  

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
N : Type u_4
inst✝⁷ : Preorder M
inst✝⁶ : Add M
inst✝⁵ : Sub M
inst✝⁴ : OrderedSub M
inst✝³ : PartialOrder N
inst✝² : Add N
inst✝¹ : Sub N
inst✝ : OrderedSub N
e : M ≃o N
h_add : ∀ (a b : M), e (a + b) = e a + e b
a b : M
e_add : M ≃+ N := { toEquiv := e.toEquiv, map_add' := h_add }
⊢ e (a - b) = e a - e b

Next tactic:
refine' le_antisymm _ (e_add.toAddHom.le_map_tsub e.monotone a b)
/-- An order isomorphism between types with ordered subtraction preserves subtraction provided that
it preserves addition. -/
theorem OrderIso.map_tsub {M N : Type*} [Preorder M] [Add M] [Sub M] [OrderedSub M]
    [PartialOrder N] [Add N] [Sub N] [OrderedSub N] (e : M ≃o N)
    (h_add : ∀ a b, e (a + b) = e a + e b) (a b : M) : e (a - b) = e a - e b := by
  let e_add : M ≃+ N := { e with map_add' := h_add }
  refine' le_antisymm _ (e_add.toAddHom.le_map_tsub e.monotone a b)
  

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
N : Type u_4
inst✝⁷ : Preorder M
inst✝⁶ : Add M
inst✝⁵ : Sub M
inst✝⁴ : OrderedSub M
inst✝³ : PartialOrder N
inst✝² : Add N
inst✝¹ : Sub N
inst✝ : OrderedSub N
e : M ≃o N
h_add : ∀ (a b : M), e (a + b) = e a + e b
a b : M
e_add : M ≃+ N := { toEquiv := e.toEquiv, map_add' := h_add }
⊢ e (a - b) ≤ e a - e b

Next tactic:
suffices e (e.symm (e a) - e.symm (e b)) ≤ e (e.symm (e a - e b)) by simpa
/-- An order isomorphism between types with ordered subtraction preserves subtraction provided that
it preserves addition. -/
theorem OrderIso.map_tsub {M N : Type*} [Preorder M] [Add M] [Sub M] [OrderedSub M]
    [PartialOrder N] [Add N] [Sub N] [OrderedSub N] (e : M ≃o N)
    (h_add : ∀ a b, e (a + b) = e a + e b) (a b : M) : e (a - b) = e a - e b := by
  let e_add : M ≃+ N := { e with map_add' := h_add }
  refine' le_antisymm _ (e_add.toAddHom.le_map_tsub e.monotone a b)
  suffices e (e.symm (e a) - e.symm (e b)) ≤ e (e.symm (e a - e b)) by 

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
N : Type u_4
inst✝⁷ : Preorder M
inst✝⁶ : Add M
inst✝⁵ : Sub M
inst✝⁴ : OrderedSub M
inst✝³ : PartialOrder N
inst✝² : Add N
inst✝¹ : Sub N
inst✝ : OrderedSub N
e : M ≃o N
h_add : ∀ (a b : M), e (a + b) = e a + e b
a b : M
e_add : M ≃+ N := { toEquiv := e.toEquiv, map_add' := h_add }
this : e ((symm e) (e a) - (symm e) (e b)) ≤ e ((symm e) (e a - e b))
⊢ e (a - b) ≤ e a - e b

Next tactic:
simpa
/-- An order isomorphism between types with ordered subtraction preserves subtraction provided that
it preserves addition. -/
theorem OrderIso.map_tsub {M N : Type*} [Preorder M] [Add M] [Sub M] [OrderedSub M]
    [PartialOrder N] [Add N] [Sub N] [OrderedSub N] (e : M ≃o N)
    (h_add : ∀ a b, e (a + b) = e a + e b) (a b : M) : e (a - b) = e a - e b := by
  let e_add : M ≃+ N := { e with map_add' := h_add }
  refine' le_antisymm _ (e_add.toAddHom.le_map_tsub e.monotone a b)
  suffices e (e.symm (e a) - e.symm (e b)) ≤ e (e.symm (e a - e b)) by simpa
  

Proof state:
α : Type u_1
β : Type u_2
M : Type u_3
N : Type u_4
inst✝⁷ : Preorder M
inst✝⁶ : Add M
inst✝⁵ : Sub M
inst✝⁴ : OrderedSub M
inst✝³ : PartialOrder N
inst✝² : Add N
inst✝¹ : Sub N
inst✝ : OrderedSub N
e : M ≃o N
h_add : ∀ (a b : M), e (a + b) = e a + e b
a b : M
e_add : M ≃+ N := { toEquiv := e.toEquiv, map_add' := h_add }
⊢ e ((symm e) (e a) - (symm e) (e b)) ≤ e ((symm e) (e a - e b))

Next tactic:
exact e.monotone (e_add.symm.toAddHom.le_map_tsub e.symm.monotone _ _)
@[simp]
theorem add_top (a : WithTop α) : a + ⊤ = ⊤ := by 

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a✝ b c d : WithTop α
x y : α
a : WithTop α
⊢ a + ⊤ = ⊤

Next tactic:
cases a
@[simp]
theorem add_top (a : WithTop α) : a + ⊤ = ⊤ := by cases a <;> 

Proof state:
case none
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y : α
⊢ none + ⊤ = ⊤

Next tactic:
rfl
@[simp]
theorem add_top (a : WithTop α) : a + ⊤ = ⊤ := by cases a <;> 

Proof state:
case some
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y val✝ : α
⊢ Option.some val✝ + ⊤ = ⊤

Next tactic:
rfl
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y : α
⊢ a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤

Next tactic:
cases a
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> 

Proof state:
case none
α : Type u
β : Type v
inst✝ : Add α
b c d : WithTop α
x y : α
⊢ none + b = ⊤ ↔ none = ⊤ ∨ b = ⊤

Next tactic:
cases b
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> 

Proof state:
case some
α : Type u
β : Type v
inst✝ : Add α
b c d : WithTop α
x y val✝ : α
⊢ Option.some val✝ + b = ⊤ ↔ Option.some val✝ = ⊤ ∨ b = ⊤

Next tactic:
cases b
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> cases b <;> 

Proof state:
case none.none
α : Type u
β : Type v
inst✝ : Add α
c d : WithTop α
x y : α
⊢ none + none = ⊤ ↔ none = ⊤ ∨ none = ⊤

Next tactic:
simp [none_eq_top, some_eq_coe, ← WithTop.coe_add]
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> cases b <;> 

Proof state:
case none.some
α : Type u
β : Type v
inst✝ : Add α
c d : WithTop α
x y val✝ : α
⊢ none + Option.some val✝ = ⊤ ↔ none = ⊤ ∨ Option.some val✝ = ⊤

Next tactic:
simp [none_eq_top, some_eq_coe, ← WithTop.coe_add]
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> cases b <;> 

Proof state:
case some.none
α : Type u
β : Type v
inst✝ : Add α
c d : WithTop α
x y val✝ : α
⊢ Option.some val✝ + none = ⊤ ↔ Option.some val✝ = ⊤ ∨ none = ⊤

Next tactic:
simp [none_eq_top, some_eq_coe, ← WithTop.coe_add]
@[simp]
theorem add_eq_top : a + b = ⊤ ↔ a = ⊤ ∨ b = ⊤ := by
  cases a <;> cases b <;> 

Proof state:
case some.some
α : Type u
β : Type v
inst✝ : Add α
c d : WithTop α
x y val✝¹ val✝ : α
⊢ Option.some val✝¹ + Option.some val✝ = ⊤ ↔ Option.some val✝¹ = ⊤ ∨ Option.some val✝ = ⊤

Next tactic:
simp [none_eq_top, some_eq_coe, ← WithTop.coe_add]
theorem add_lt_top [LT α] {a b : WithTop α} : a + b < ⊤ ↔ a < ⊤ ∧ b < ⊤ := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : Add α
a✝ b✝ c d : WithTop α
x y : α
inst✝ : LT α
a b : WithTop α
⊢ a + b < ⊤ ↔ a < ⊤ ∧ b < ⊤

Next tactic:
simp_rw [WithTop.lt_top_iff_ne_top, add_ne_top]
theorem add_eq_coe :
    ∀ {a b : WithTop α} {c : α}, a + b = c ↔ ∃ a' b' : α, ↑a' = a ∧ ↑b' = b ∧ a' + b' = c
  | none, b, c => by 

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a b✝ c✝ d : WithTop α
x y : α
b : WithTop α
c : α
⊢ none + b = ↑c ↔ ∃ a' b', ↑a' = none ∧ ↑b' = b ∧ a' + b' = c

Next tactic:
simp [none_eq_top]
theorem add_eq_coe :
    ∀ {a b : WithTop α} {c : α}, a + b = c ↔ ∃ a' b' : α, ↑a' = a ∧ ↑b' = b ∧ a' + b' = c
  | none, b, c => by simp [none_eq_top]
  | Option.some a, none, c => by 

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a✝ b c✝ d : WithTop α
x y a c : α
⊢ Option.some a + none = ↑c ↔ ∃ a' b', ↑a' = Option.some a ∧ ↑b' = none ∧ a' + b' = c

Next tactic:
simp [none_eq_top]
theorem add_eq_coe :
    ∀ {a b : WithTop α} {c : α}, a + b = c ↔ ∃ a' b' : α, ↑a' = a ∧ ↑b' = b ∧ a' + b' = c
  | none, b, c => by simp [none_eq_top]
  | Option.some a, none, c => by simp [none_eq_top]
  | Option.some a, Option.some b, c =>
  by 

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a✝ b✝ c✝ d : WithTop α
x y a b c : α
⊢ Option.some a + Option.some b = ↑c ↔ ∃ a' b', ↑a' = Option.some a ∧ ↑b' = Option.some b ∧ a' + b' = c

Next tactic:
simp only [some_eq_coe, ← coe_add, coe_eq_coe, exists_and_left, exists_eq_left]
theorem add_coe_eq_top_iff {x : WithTop α} {y : α} : x + y = ⊤ ↔ x = ⊤ := by
  

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x✝ y✝ : α
x : WithTop α
y : α
⊢ x + ↑y = ⊤ ↔ x = ⊤

Next tactic:
induction x using WithTop.recTopCoe
theorem add_coe_eq_top_iff {x : WithTop α} {y : α} : x + y = ⊤ ↔ x = ⊤ := by
  induction x using WithTop.recTopCoe <;> 

Proof state:
case top
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y✝ y : α
⊢ ⊤ + ↑y = ⊤ ↔ ⊤ = ⊤

Next tactic:
simp [← coe_add]
theorem add_coe_eq_top_iff {x : WithTop α} {y : α} : x + y = ⊤ ↔ x = ⊤ := by
  induction x using WithTop.recTopCoe <;> 

Proof state:
case coe
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y✝ y a✝ : α
⊢ ↑a✝ + ↑y = ⊤ ↔ ↑a✝ = ⊤

Next tactic:
simp [← coe_add]
theorem coe_add_eq_top_iff {y : WithTop α} : ↑x + y = ⊤ ↔ y = ⊤ := by
  

Proof state:
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y✝ : α
y : WithTop α
⊢ ↑x + y = ⊤ ↔ y = ⊤

Next tactic:
induction y using WithTop.recTopCoe
theorem coe_add_eq_top_iff {y : WithTop α} : ↑x + y = ⊤ ↔ y = ⊤ := by
  induction y using WithTop.recTopCoe <;> 

Proof state:
case top
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y : α
⊢ ↑x + ⊤ = ⊤ ↔ ⊤ = ⊤

Next tactic:
simp [← coe_add]
theorem coe_add_eq_top_iff {y : WithTop α} : ↑x + y = ⊤ ↔ y = ⊤ := by
  induction y using WithTop.recTopCoe <;> 

Proof state:
case coe
α : Type u
β : Type v
inst✝ : Add α
a b c d : WithTop α
x y a✝ : α
⊢ ↑x + ↑a✝ = ⊤ ↔ ↑a✝ = ⊤

Next tactic:
simp [← coe_add]
theorem add_right_cancel_iff [IsRightCancelAdd α] (ha : a ≠ ⊤) : b + a = c + a ↔ b = c := by
  

Proof state:
α : Type u
β : Type v
inst✝¹ : Add α
a b c d : WithTop α
x y : α
inst✝ : IsRightCancelAdd α
ha : a ≠ ⊤
⊢ b + a = c + a ↔ b = c

Next tactic:
lift a to α using ha
theorem add_right_cancel_iff [IsRightCancelAdd α] (ha : a ≠ ⊤) : b + a = c + a ↔ b = c := by
  lift a to α using ha
  

Proof state:
case intro
α : Type u
β : Type v
inst✝¹ : Add α
b c d : WithTop α
x y : α
inst✝ : IsRightCancelAdd α
a : α
⊢ b + ↑a = c + ↑a ↔ b = c

Next tactic:
obtain rfl | hb := (eq_or_ne b ⊤)
theorem add_right_cancel_iff [IsRightCancelAdd α] (ha : a ≠ ⊤) : b + a = c + a ↔ b = c := by
  lift a to α using ha
  obtain rfl | hb := (eq_or_ne b ⊤)
  · 

Proof state:
case intro.inl
α : Type u
β : Type v
inst✝¹ : Add α
c d : WithTop α
x y : α
inst✝ : IsRightCancelAdd α
a : α
⊢ ⊤ + ↑a = c + ↑a ↔ ⊤ = c

Next tactic:
rw [top_add, eq_comm, WithTop.add_coe_eq_top_iff, eq_comm]
theorem add_right_cancel_iff [IsRightCancelAdd α] (ha : a ≠ ⊤) : b + a = c + a ↔ b = c := by
  lift a to α using ha
  obtain rfl | hb := (eq_or_ne b ⊤)
  · rw [top_add, eq_comm, WithTop.add_coe_eq_top_iff, eq_comm]
  

Proof state:
case intro.inr
α : Type u
β : Type v
inst✝¹ : Add α
b c d : WithTop α
x y : α
inst✝ : IsRightCancelAdd α
a : α
hb : b ≠ ⊤
⊢ b + ↑a = c + ↑a ↔ b = c

Next tactic:
lift b to α using hb