data.prod.basicMathlib.Data.Prod.Basic

This file has been ported!

Changes since the initial port

The following section lists changes to this file in mathlib3 and mathlib4 that occured after the initial port. Most recent changes are shown first. Hovering over a commit will show all commits associated with the same mathlib3 commit.

Changes in mathlib3

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(last sync)

feat(group_theory/order_of_element): Order in α × β (#18719)

The order of (a, b) is the lcm of the orders of a and b. Match pow and zpow lemmas. Also some variables noise because I could not use x to mean what I wanted, and incidentally the type A was mostly unused.

Diff
@@ -97,7 +97,7 @@ funext (λ p, ext (map_fst f g p) (map_snd f g p))
 lemma id_prod : (λ (p : α × β), (p.1, p.2)) = id :=
 funext $ λ ⟨a, b⟩, rfl
 
-lemma map_id : (prod.map (@id α) (@id β)) = id :=
+@[simp] lemma map_id : (prod.map (@id α) (@id β)) = id :=
 id_prod
 
 lemma fst_surjective [h : nonempty β] : function.surjective (@fst α β) :=

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

refactor(*): move all mk_simp_attribute commands to 1 file (#19223)
Diff
@@ -37,7 +37,9 @@ prod.exists
 
 @[simp] lemma fst_comp_mk (x : α) : prod.fst ∘ (prod.mk x : β → α × β) = function.const β x := rfl
 
-@[simp] lemma map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) := rfl
+@[simp, mfld_simps] lemma map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) :
+  map f g (a, b) = (f a, g b) :=
+rfl
 
 lemma map_fst (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).1 = f (p.1) := rfl
 

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(data/prod): bijectivity of prod.map (#18446)

I needed this for showing a statement about invertibility of a map built with linear_map.prod_map (aka a "block diagonal" linear map), where the nonempty conditions are trivially true.

Forward-port will be at https://github.com/leanprover-community/mathlib4/pull/2346

Diff
@@ -260,3 +260,58 @@ lemma involutive.prod_map {f : α → α} {g : β → β} :
 left_inverse.prod_map
 
 end function
+
+namespace prod
+open function
+
+@[simp] lemma map_injective [nonempty α] [nonempty β] {f : α → γ} {g : β → δ} :
+  injective (map f g) ↔ injective f ∧ injective g :=
+⟨λ h, ⟨λ a₁ a₂ ha, begin
+  inhabit β,
+  injection @h (a₁, default) (a₂, default) (congr_arg (λ c : γ, prod.mk c (g default)) ha : _),
+end, λ b₁ b₂ hb, begin
+  inhabit α,
+  injection @h (default, b₁) (default, b₂) (congr_arg (prod.mk (f default)) hb : _),
+end⟩, λ h, h.1.prod_map h.2⟩
+
+@[simp] lemma map_surjective [nonempty γ] [nonempty δ] {f : α → γ} {g : β → δ} :
+  surjective (map f g) ↔ surjective f ∧ surjective g :=
+⟨λ h, ⟨λ c, begin
+  inhabit δ,
+  obtain ⟨⟨a, b⟩, h⟩ := h (c, default),
+  exact ⟨a, congr_arg prod.fst h⟩,
+end, λ d, begin
+  inhabit γ,
+  obtain ⟨⟨a, b⟩, h⟩ := h (default, d),
+  exact ⟨b, congr_arg prod.snd h⟩,
+end⟩, λ h, h.1.prod_map h.2⟩
+
+@[simp] lemma map_bijective [nonempty α] [nonempty β] {f : α → γ} {g : β → δ} :
+  bijective (map f g) ↔ bijective f ∧ bijective g :=
+begin
+  haveI := nonempty.map f ‹_›,
+  haveI := nonempty.map g ‹_›,
+  exact (map_injective.and map_surjective).trans (and_and_and_comm _ _ _ _)
+end
+
+@[simp] lemma map_left_inverse [nonempty β] [nonempty δ]
+  {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α} {g₂ : δ → γ} :
+  left_inverse (map f₁ g₁) (map f₂ g₂) ↔ left_inverse f₁ f₂ ∧ left_inverse g₁ g₂ :=
+⟨λ h, ⟨λ b, begin
+  inhabit δ,
+  exact congr_arg prod.fst (h (b, default)),
+end, λ d, begin
+  inhabit β,
+  exact congr_arg prod.snd (h (default, d)),
+end⟩, λ h, h.1.prod_map h.2⟩
+
+@[simp] lemma map_right_inverse [nonempty α] [nonempty γ]
+  {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α} {g₂ : δ → γ} :
+  right_inverse (map f₁ g₁) (map f₂ g₂) ↔ right_inverse f₁ f₂ ∧ right_inverse g₁ g₂ :=
+map_left_inverse
+
+@[simp] lemma map_involutive [nonempty α] [nonempty β] {f : α → α} {g : β → β} :
+  involutive (map f g) ↔ involutive f ∧ involutive g :=
+map_left_inverse
+
+end prod

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(data/prod/basic): prod.lex is trichotomous (#17931)

or irreflexive when the base relations are.

Diff
@@ -68,8 +68,9 @@ lemma map_map {ε ζ : Type*}
   prod.map g g' (prod.map f f' x) = prod.map (g ∘ f) (g' ∘ f') x :=
 rfl
 
-@[simp] theorem mk.inj_iff {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) = (a₂, b₂) ↔ (a₁ = a₂ ∧ b₁ = b₂) :=
-⟨prod.mk.inj, by cc⟩
+variables {a a₁ a₂ : α} {b b₁ b₂ : β}
+
+@[simp] lemma mk.inj_iff : (a₁, b₁) = (a₂, b₂) ↔ a₁ = a₂ ∧ b₁ = b₂ := ⟨prod.mk.inj, by cc⟩
 
 lemma mk.inj_left {α β : Type*} (a : α) :
   function.injective (prod.mk a : β → α × β) :=
@@ -79,6 +80,9 @@ lemma mk.inj_right {α β : Type*} (b : β) :
   function.injective (λ a, prod.mk a b : α → α × β) :=
 by { intros b₁ b₂ h, by simpa only [and_true, eq_self_iff_true, mk.inj_iff] using h }
 
+lemma mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ := (mk.inj_left _).eq_iff
+lemma mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).eq_iff
+
 lemma ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 :=
 by rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
 
@@ -148,6 +152,8 @@ lemma fst_eq_iff : ∀ {p : α × β} {x : α}, p.1 = x ↔ p = (x, p.2)
 lemma snd_eq_iff : ∀ {p : α × β} {x : β}, p.2 = x ↔ p = (p.1, x)
 | ⟨a, b⟩ x := by simp
 
+variables {r : α → α → Prop} {s : β → β → Prop} {x y : α × β}
+
 theorem lex_def (r : α → α → Prop) (s : β → β → Prop)
   {p q : α × β} : prod.lex r s p q ↔ r p.1 q.1 ∨ p.1 = q.1 ∧ s p.2 q.2 :=
 ⟨λ h, by cases h; simp *,
@@ -157,6 +163,8 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop)
    by change a = c at e; subst e; exact lex.right _ h
  end⟩
 
+lemma lex_iff : lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 := lex_def _ _
+
 instance lex.decidable [decidable_eq α]
   (r : α → α → Prop) (s : β → β → Prop) [decidable_rel r] [decidable_rel s] :
   decidable_rel (prod.lex r s) :=
@@ -178,6 +186,9 @@ instance is_refl_right {r : α → α → Prop} {s : β → β → Prop} [is_ref
   is_refl (α × β) (lex r s) :=
 ⟨lex.refl_right _ _⟩
 
+instance is_irrefl [is_irrefl α r] [is_irrefl β s] : is_irrefl (α × β) (lex r s) :=
+⟨by rintro ⟨i, a⟩ (⟨_, _, h⟩ | ⟨_, h⟩); exact irrefl _ h⟩
+
 @[trans] lemma lex.trans {r : α → α → Prop} {s : β → β → Prop} [is_trans α r] [is_trans β s] :
   ∀ {x y z : α × β}, prod.lex r s x y → prod.lex r s y z → prod.lex r s x z
 | (x₁, x₂) (y₁, y₂) (z₁, z₂) (lex.left _ _ hxy₁) (lex.left _ _ hyz₁) :=
@@ -212,6 +223,15 @@ instance is_total_right {r : α → α → Prop} {s : β → β → Prop} [is_tr
   { exact or.inr (lex.left _ _ hji) }
 end⟩
 
+instance is_trichotomous [is_trichotomous α r] [is_trichotomous β s] :
+  is_trichotomous (α × β) (lex r s) :=
+⟨λ ⟨i, a⟩ ⟨j, b⟩, begin
+  obtain hij | rfl | hji := trichotomous_of r i j,
+  { exact or.inl (lex.left _ _ hij) },
+  { exact (trichotomous_of s a b).imp3 (lex.right _) (congr_arg _) (lex.right _) },
+  { exact or.inr (or.inr $ lex.left _ _ hji) }
+end⟩
+
 end prod
 
 open prod

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -316,7 +316,7 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × 
   ⟨fun h => by cases h <;> simp [*], fun h =>
     match p, q, h with
     | (a, b), (c, d), Or.inl h => Lex.left _ _ h
-    | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e  <;> subst e <;> exact lex.right _ h⟩
+    | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e <;> subst e <;> exact lex.right _ h⟩
 #align prod.lex_def Prod.lex_def
 -/
 
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 -/
-import Mathbin.Tactic.Basic
-import Mathbin.Logic.Function.Basic
+import Tactic.Basic
+import Logic.Function.Basic
 
 #align_import data.prod.basic from "leanprover-community/mathlib"@"d07245fd37786daa997af4f1a73a49fa3b748408"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2017 Johannes Hölzl. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
-
-! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit d07245fd37786daa997af4f1a73a49fa3b748408
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Tactic.Basic
 import Mathbin.Logic.Function.Basic
 
+#align_import data.prod.basic from "leanprover-community/mathlib"@"d07245fd37786daa997af4f1a73a49fa3b748408"
+
 /-!
 # Extra facts about `prod`
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit 48fb5b5280e7c81672afc9524185ae994553ebf4
+! leanprover-community/mathlib commit d07245fd37786daa997af4f1a73a49fa3b748408
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -183,6 +183,7 @@ theorem id_prod : (fun p : α × β => (p.1, p.2)) = id :=
 -/
 
 #print Prod.map_id /-
+@[simp]
 theorem map_id : Prod.map (@id α) (@id β) = id :=
   id_prod
 #align prod.map_id Prod.map_id
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit bd9851ca476957ea4549eb19b40e7b5ade9428cc
+! leanprover-community/mathlib commit 48fb5b5280e7c81672afc9524185ae994553ebf4
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -73,7 +73,7 @@ theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Func
 -/
 
 #print Prod.map_mk /-
-@[simp]
+@[simp, mfld_simps]
 theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) :=
   rfl
 #align prod.map_mk Prod.map_mk
Diff
@@ -23,30 +23,40 @@ This file defines `prod.swap : α × β → β × α` and proves various simple
 
 variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
 
+#print Prod_map /-
 @[simp]
 theorem Prod_map (f : α → γ) (g : β → δ) (p : α × β) : Prod.map f g p = (f p.1, g p.2) :=
   rfl
 #align prod_map Prod_map
+-/
 
 namespace Prod
 
+#print Prod.forall /-
 @[simp]
 theorem forall {p : α × β → Prop} : (∀ x, p x) ↔ ∀ a b, p (a, b) :=
   ⟨fun h a b => h (a, b), fun h ⟨a, b⟩ => h a b⟩
 #align prod.forall Prod.forall
+-/
 
+#print Prod.exists /-
 @[simp]
 theorem exists {p : α × β → Prop} : (∃ x, p x) ↔ ∃ a b, p (a, b) :=
   ⟨fun ⟨⟨a, b⟩, h⟩ => ⟨a, b, h⟩, fun ⟨a, b, h⟩ => ⟨⟨a, b⟩, h⟩⟩
 #align prod.exists Prod.exists
+-/
 
+#print Prod.forall' /-
 theorem forall' {p : α → β → Prop} : (∀ x : α × β, p x.1 x.2) ↔ ∀ a b, p a b :=
   Prod.forall
 #align prod.forall' Prod.forall'
+-/
 
+#print Prod.exists' /-
 theorem exists' {p : α → β → Prop} : (∃ x : α × β, p x.1 x.2) ↔ ∃ a b, p a b :=
   Prod.exists
 #align prod.exists' Prod.exists'
+-/
 
 #print Prod.snd_comp_mk /-
 @[simp]
@@ -55,32 +65,45 @@ theorem snd_comp_mk (x : α) : Prod.snd ∘ (Prod.mk x : β → α × β) = id :
 #align prod.snd_comp_mk Prod.snd_comp_mk
 -/
 
+#print Prod.fst_comp_mk /-
 @[simp]
 theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Function.const β x :=
   rfl
 #align prod.fst_comp_mk Prod.fst_comp_mk
+-/
 
+#print Prod.map_mk /-
 @[simp]
 theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) :=
   rfl
 #align prod.map_mk Prod.map_mk
+-/
 
+#print Prod.map_fst /-
 theorem map_fst (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).1 = f p.1 :=
   rfl
 #align prod.map_fst Prod.map_fst
+-/
 
+#print Prod.map_snd /-
 theorem map_snd (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).2 = g p.2 :=
   rfl
 #align prod.map_snd Prod.map_snd
+-/
 
+#print Prod.map_fst' /-
 theorem map_fst' (f : α → γ) (g : β → δ) : Prod.fst ∘ map f g = f ∘ Prod.fst :=
   funext <| map_fst f g
 #align prod.map_fst' Prod.map_fst'
+-/
 
+#print Prod.map_snd' /-
 theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘ Prod.snd :=
   funext <| map_snd f g
 #align prod.map_snd' Prod.map_snd'
+-/
 
+#print Prod.map_comp_map /-
 /-- Composing a `prod.map` with another `prod.map` is equal to
 a single `prod.map` of composed functions.
 -/
@@ -88,7 +111,9 @@ theorem map_comp_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β 
     Prod.map g g' ∘ Prod.map f f' = Prod.map (g ∘ f) (g' ∘ f') :=
   rfl
 #align prod.map_comp_map Prod.map_comp_map
+-/
 
+#print Prod.map_map /-
 /-- Composing a `prod.map` with another `prod.map` is equal to
 a single `prod.map` of composed functions, fully applied.
 -/
@@ -96,51 +121,72 @@ theorem map_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε
     Prod.map g g' (Prod.map f f' x) = Prod.map (g ∘ f) (g' ∘ f') x :=
   rfl
 #align prod.map_map Prod.map_map
+-/
 
 variable {a a₁ a₂ : α} {b b₁ b₂ : β}
 
+#print Prod.mk.inj_iff /-
 @[simp]
 theorem mk.inj_iff : (a₁, b₁) = (a₂, b₂) ↔ a₁ = a₂ ∧ b₁ = b₂ :=
   ⟨Prod.mk.inj, by cc⟩
 #align prod.mk.inj_iff Prod.mk.inj_iff
+-/
 
+#print Prod.mk.inj_left /-
 theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
   intro b₁ b₂ h; simpa only [true_and_iff, Prod.mk.inj_iff, eq_self_iff_true] using h
 #align prod.mk.inj_left Prod.mk.inj_left
+-/
 
+#print Prod.mk.inj_right /-
 theorem mk.inj_right {α β : Type _} (b : β) :
     Function.Injective (fun a => Prod.mk a b : α → α × β) := by intro b₁ b₂ h;
   · simpa only [and_true_iff, eq_self_iff_true, mk.inj_iff] using h
 #align prod.mk.inj_right Prod.mk.inj_right
+-/
 
+#print Prod.mk_inj_left /-
 theorem mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ :=
   (mk.inj_left _).eq_iff
 #align prod.mk_inj_left Prod.mk_inj_left
+-/
 
+#print Prod.mk_inj_right /-
 theorem mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ :=
   (mk.inj_right _).eq_iff
 #align prod.mk_inj_right Prod.mk_inj_right
+-/
 
+#print Prod.ext_iff /-
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
   rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
 #align prod.ext_iff Prod.ext_iff
+-/
 
+#print Prod.ext /-
 @[ext]
 theorem ext {α β} {p q : α × β} (h₁ : p.1 = q.1) (h₂ : p.2 = q.2) : p = q :=
   ext_iff.2 ⟨h₁, h₂⟩
 #align prod.ext Prod.ext
+-/
 
+#print Prod.map_def /-
 theorem map_def {f : α → γ} {g : β → δ} : Prod.map f g = fun p : α × β => (f p.1, g p.2) :=
   funext fun p => ext (map_fst f g p) (map_snd f g p)
 #align prod.map_def Prod.map_def
+-/
 
+#print Prod.id_prod /-
 theorem id_prod : (fun p : α × β => (p.1, p.2)) = id :=
   funext fun ⟨a, b⟩ => rfl
 #align prod.id_prod Prod.id_prod
+-/
 
+#print Prod.map_id /-
 theorem map_id : Prod.map (@id α) (@id β) = id :=
   id_prod
 #align prod.map_id Prod.map_id
+-/
 
 #print Prod.fst_surjective /-
 theorem fst_surjective [h : Nonempty β] : Function.Surjective (@fst α β) := fun x =>
@@ -148,9 +194,11 @@ theorem fst_surjective [h : Nonempty β] : Function.Surjective (@fst α β) := f
 #align prod.fst_surjective Prod.fst_surjective
 -/
 
+#print Prod.snd_surjective /-
 theorem snd_surjective [h : Nonempty α] : Function.Surjective (@snd α β) := fun y =>
   h.elim fun x => ⟨⟨x, y⟩, rfl⟩
 #align prod.snd_surjective Prod.snd_surjective
+-/
 
 #print Prod.fst_injective /-
 theorem fst_injective [Subsingleton β] : Function.Injective (@fst α β) := fun x y h =>
@@ -158,9 +206,11 @@ theorem fst_injective [Subsingleton β] : Function.Injective (@fst α β) := fun
 #align prod.fst_injective Prod.fst_injective
 -/
 
+#print Prod.snd_injective /-
 theorem snd_injective [Subsingleton α] : Function.Injective (@snd α β) := fun x y h =>
   ext (Subsingleton.elim _ _) h
 #align prod.snd_injective Prod.snd_injective
+-/
 
 #print Prod.swap /-
 /-- Swap the factors of a product. `swap (a, b) = (b, a)` -/
@@ -168,72 +218,101 @@ def swap : α × β → β × α := fun p => (p.2, p.1)
 #align prod.swap Prod.swap
 -/
 
+#print Prod.swap_swap /-
 @[simp]
 theorem swap_swap : ∀ x : α × β, swap (swap x) = x
   | ⟨a, b⟩ => rfl
 #align prod.swap_swap Prod.swap_swap
+-/
 
+#print Prod.fst_swap /-
 @[simp]
 theorem fst_swap {p : α × β} : (swap p).1 = p.2 :=
   rfl
 #align prod.fst_swap Prod.fst_swap
+-/
 
+#print Prod.snd_swap /-
 @[simp]
 theorem snd_swap {p : α × β} : (swap p).2 = p.1 :=
   rfl
 #align prod.snd_swap Prod.snd_swap
+-/
 
+#print Prod.swap_prod_mk /-
 @[simp]
 theorem swap_prod_mk {a : α} {b : β} : swap (a, b) = (b, a) :=
   rfl
 #align prod.swap_prod_mk Prod.swap_prod_mk
+-/
 
+#print Prod.swap_swap_eq /-
 @[simp]
 theorem swap_swap_eq : swap ∘ swap = @id (α × β) :=
   funext swap_swap
 #align prod.swap_swap_eq Prod.swap_swap_eq
+-/
 
+#print Prod.swap_leftInverse /-
 @[simp]
 theorem swap_leftInverse : Function.LeftInverse (@swap α β) swap :=
   swap_swap
 #align prod.swap_left_inverse Prod.swap_leftInverse
+-/
 
+#print Prod.swap_rightInverse /-
 @[simp]
 theorem swap_rightInverse : Function.RightInverse (@swap α β) swap :=
   swap_swap
 #align prod.swap_right_inverse Prod.swap_rightInverse
+-/
 
+#print Prod.swap_injective /-
 theorem swap_injective : Function.Injective (@swap α β) :=
   swap_leftInverse.Injective
 #align prod.swap_injective Prod.swap_injective
+-/
 
+#print Prod.swap_surjective /-
 theorem swap_surjective : Function.Surjective (@swap α β) :=
   swap_leftInverse.Surjective
 #align prod.swap_surjective Prod.swap_surjective
+-/
 
+#print Prod.swap_bijective /-
 theorem swap_bijective : Function.Bijective (@swap α β) :=
   ⟨swap_injective, swap_surjective⟩
 #align prod.swap_bijective Prod.swap_bijective
+-/
 
+#print Prod.swap_inj /-
 @[simp]
 theorem swap_inj {p q : α × β} : swap p = swap q ↔ p = q :=
   swap_injective.eq_iff
 #align prod.swap_inj Prod.swap_inj
+-/
 
+#print Prod.eq_iff_fst_eq_snd_eq /-
 theorem eq_iff_fst_eq_snd_eq : ∀ {p q : α × β}, p = q ↔ p.1 = q.1 ∧ p.2 = q.2
   | ⟨p₁, p₂⟩, ⟨q₁, q₂⟩ => by simp
 #align prod.eq_iff_fst_eq_snd_eq Prod.eq_iff_fst_eq_snd_eq
+-/
 
+#print Prod.fst_eq_iff /-
 theorem fst_eq_iff : ∀ {p : α × β} {x : α}, p.1 = x ↔ p = (x, p.2)
   | ⟨a, b⟩, x => by simp
 #align prod.fst_eq_iff Prod.fst_eq_iff
+-/
 
+#print Prod.snd_eq_iff /-
 theorem snd_eq_iff : ∀ {p : α × β} {x : β}, p.2 = x ↔ p = (p.1, x)
   | ⟨a, b⟩, x => by simp
 #align prod.snd_eq_iff Prod.snd_eq_iff
+-/
 
 variable {r : α → α → Prop} {s : β → β → Prop} {x y : α × β}
 
+#print Prod.lex_def /-
 theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × β} :
     Prod.Lex r s p q ↔ r p.1 q.1 ∨ p.1 = q.1 ∧ s p.2 q.2 :=
   ⟨fun h => by cases h <;> simp [*], fun h =>
@@ -241,10 +320,13 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × 
     | (a, b), (c, d), Or.inl h => Lex.left _ _ h
     | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e  <;> subst e <;> exact lex.right _ h⟩
 #align prod.lex_def Prod.lex_def
+-/
 
+#print Prod.lex_iff /-
 theorem lex_iff : Lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 :=
   lex_def _ _
 #align prod.lex_iff Prod.lex_iff
+-/
 
 #print Prod.Lex.decidable /-
 instance Lex.decidable [DecidableEq α] (r : α → α → Prop) (s : β → β → Prop) [DecidableRel r]
@@ -253,10 +335,12 @@ instance Lex.decidable [DecidableEq α] (r : α → α → Prop) (s : β → β
 #align prod.lex.decidable Prod.Lex.decidable
 -/
 
+#print Prod.Lex.refl_left /-
 @[refl]
 theorem Lex.refl_left (r : α → α → Prop) (s : β → β → Prop) [IsRefl α r] : ∀ x, Prod.Lex r s x x
   | (x₁, x₂) => Lex.left _ _ (refl _)
 #align prod.lex.refl_left Prod.Lex.refl_left
+-/
 
 instance isRefl_left {r : α → α → Prop} {s : β → β → Prop} [IsRefl α r] :
     IsRefl (α × β) (Lex r s) :=
@@ -281,6 +365,7 @@ instance isIrrefl [IsIrrefl α r] [IsIrrefl β s] : IsIrrefl (α × β) (Lex r s
 #align prod.is_irrefl Prod.isIrrefl
 -/
 
+#print Prod.Lex.trans /-
 @[trans]
 theorem Lex.trans {r : α → α → Prop} {s : β → β → Prop} [IsTrans α r] [IsTrans β s] :
     ∀ {x y z : α × β}, Prod.Lex r s x y → Prod.Lex r s y z → Prod.Lex r s x z
@@ -291,6 +376,7 @@ theorem Lex.trans {r : α → α → Prop} {s : β → β → Prop} [IsTrans α
   | (x₁, x₂), (y₁, y₂), (z₁, z₂), lex.right _ hxy₂, lex.right _ hyz₂ =>
     Lex.right _ (trans hxy₂ hyz₂)
 #align prod.lex.trans Prod.Lex.trans
+-/
 
 instance {r : α → α → Prop} {s : β → β → Prop} [IsTrans α r] [IsTrans β s] :
     IsTrans (α × β) (Lex r s) :=
@@ -340,35 +426,47 @@ namespace Function
 
 variable {f : α → γ} {g : β → δ} {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α} {g₂ : δ → γ}
 
+#print Function.Injective.Prod_map /-
 theorem Injective.Prod_map (hf : Injective f) (hg : Injective g) : Injective (map f g) :=
   fun x y h => ext (hf (ext_iff.1 h).1) (hg <| (ext_iff.1 h).2)
 #align function.injective.prod_map Function.Injective.Prod_map
+-/
 
+#print Function.Surjective.Prod_map /-
 theorem Surjective.Prod_map (hf : Surjective f) (hg : Surjective g) : Surjective (map f g) :=
   fun p =>
   let ⟨x, hx⟩ := hf p.1
   let ⟨y, hy⟩ := hg p.2
   ⟨(x, y), Prod.ext hx hy⟩
 #align function.surjective.prod_map Function.Surjective.Prod_map
+-/
 
+#print Function.Bijective.Prod_map /-
 theorem Bijective.Prod_map (hf : Bijective f) (hg : Bijective g) : Bijective (map f g) :=
   ⟨hf.1.Prod_map hg.1, hf.2.Prod_map hg.2⟩
 #align function.bijective.prod_map Function.Bijective.Prod_map
+-/
 
+#print Function.LeftInverse.Prod_map /-
 theorem LeftInverse.Prod_map (hf : LeftInverse f₁ f₂) (hg : LeftInverse g₁ g₂) :
     LeftInverse (map f₁ g₁) (map f₂ g₂) := fun a => by
   rw [Prod.map_map, hf.comp_eq_id, hg.comp_eq_id, map_id, id]
 #align function.left_inverse.prod_map Function.LeftInverse.Prod_map
+-/
 
+#print Function.RightInverse.Prod_map /-
 theorem RightInverse.Prod_map :
     RightInverse f₁ f₂ → RightInverse g₁ g₂ → RightInverse (map f₁ g₁) (map f₂ g₂) :=
   LeftInverse.Prod_map
 #align function.right_inverse.prod_map Function.RightInverse.Prod_map
+-/
 
+#print Function.Involutive.Prod_map /-
 theorem Involutive.Prod_map {f : α → α} {g : β → β} :
     Involutive f → Involutive g → Involutive (map f g) :=
   LeftInverse.Prod_map
 #align function.involutive.prod_map Function.Involutive.Prod_map
+-/
 
 end Function
 
@@ -376,6 +474,7 @@ namespace Prod
 
 open Function
 
+#print Prod.map_injective /-
 @[simp]
 theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Injective (map f g) ↔ Injective f ∧ Injective g :=
@@ -389,7 +488,9 @@ theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
       injection @h (default, b₁) (default, b₂) (congr_arg (Prod.mk (f default)) hb : _)⟩,
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_injective Prod.map_injective
+-/
 
+#print Prod.map_surjective /-
 @[simp]
 theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → δ} :
     Surjective (map f g) ↔ Surjective f ∧ Surjective g :=
@@ -404,7 +505,9 @@ theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → 
       exact ⟨b, congr_arg Prod.snd h⟩⟩,
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_surjective Prod.map_surjective
+-/
 
+#print Prod.map_bijective /-
 @[simp]
 theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Bijective (map f g) ↔ Bijective f ∧ Bijective g :=
@@ -413,7 +516,9 @@ theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
   haveI := Nonempty.map g ‹_›
   exact (map_injective.and map_surjective).trans (and_and_and_comm _ _ _ _)
 #align prod.map_bijective Prod.map_bijective
+-/
 
+#print Prod.map_leftInverse /-
 @[simp]
 theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : LeftInverse (map f₁ g₁) (map f₂ g₂) ↔ LeftInverse f₁ f₂ ∧ LeftInverse g₁ g₂ :=
@@ -426,18 +531,23 @@ theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : 
       exact congr_arg Prod.snd (h (default, d))⟩,
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_left_inverse Prod.map_leftInverse
+-/
 
+#print Prod.map_rightInverse /-
 @[simp]
 theorem map_rightInverse [Nonempty α] [Nonempty γ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : RightInverse (map f₁ g₁) (map f₂ g₂) ↔ RightInverse f₁ f₂ ∧ RightInverse g₁ g₂ :=
   map_leftInverse
 #align prod.map_right_inverse Prod.map_rightInverse
+-/
 
+#print Prod.map_involutive /-
 @[simp]
 theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → β} :
     Involutive (map f g) ↔ Involutive f ∧ Involutive g :=
   map_leftInverse
 #align prod.map_involutive Prod.map_involutive
+-/
 
 end Prod
 
Diff
@@ -239,7 +239,7 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × 
   ⟨fun h => by cases h <;> simp [*], fun h =>
     match p, q, h with
     | (a, b), (c, d), Or.inl h => Lex.left _ _ h
-    | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e <;> subst e <;> exact lex.right _ h⟩
+    | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e  <;> subst e <;> exact lex.right _ h⟩
 #align prod.lex_def Prod.lex_def
 
 theorem lex_iff : Lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 :=
Diff
@@ -23,12 +23,6 @@ This file defines `prod.swap : α × β → β × α` and proves various simple
 
 variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
 
-/- warning: prod_map -> Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ) (p : Prod.{u1, u2} α β), Eq.{max (succ u3) (succ u4)} (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g p) (Prod.mk.{u3, u4} γ δ (f (Prod.fst.{u1, u2} α β p)) (g (Prod.snd.{u1, u2} α β p)))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u2}} {δ : Type.{u1}} (f : α -> γ) (g : β -> δ) (p : Prod.{u4, u3} α β), Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} γ δ) (Prod.map.{u4, u2, u3, u1} α γ β δ f g p) (Prod.mk.{u2, u1} γ δ (f (Prod.fst.{u4, u3} α β p)) (g (Prod.snd.{u4, u3} α β p)))
-Case conversion may be inaccurate. Consider using '#align prod_map Prod_mapₓ'. -/
 @[simp]
 theorem Prod_map (f : α → γ) (g : β → δ) (p : α × β) : Prod.map f g p = (f p.1, g p.2) :=
   rfl
@@ -36,44 +30,20 @@ theorem Prod_map (f : α → γ) (g : β → δ) (p : α × β) : Prod.map f g p
 
 namespace Prod
 
-/- warning: prod.forall -> Prod.forall is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : (Prod.{u1, u2} α β) -> Prop}, Iff (forall (x : Prod.{u1, u2} α β), p x) (forall (a : α) (b : β), p (Prod.mk.{u1, u2} α β a b))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : (Prod.{u2, u1} α β) -> Prop}, Iff (forall (x : Prod.{u2, u1} α β), p x) (forall (a : α) (b : β), p (Prod.mk.{u2, u1} α β a b))
-Case conversion may be inaccurate. Consider using '#align prod.forall Prod.forallₓ'. -/
 @[simp]
 theorem forall {p : α × β → Prop} : (∀ x, p x) ↔ ∀ a b, p (a, b) :=
   ⟨fun h a b => h (a, b), fun h ⟨a, b⟩ => h a b⟩
 #align prod.forall Prod.forall
 
-/- warning: prod.exists -> Prod.exists is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : (Prod.{u1, u2} α β) -> Prop}, Iff (Exists.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => p x)) (Exists.{succ u1} α (fun (a : α) => Exists.{succ u2} β (fun (b : β) => p (Prod.mk.{u1, u2} α β a b))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : (Prod.{u2, u1} α β) -> Prop}, Iff (Exists.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => p x)) (Exists.{succ u2} α (fun (a : α) => Exists.{succ u1} β (fun (b : β) => p (Prod.mk.{u2, u1} α β a b))))
-Case conversion may be inaccurate. Consider using '#align prod.exists Prod.existsₓ'. -/
 @[simp]
 theorem exists {p : α × β → Prop} : (∃ x, p x) ↔ ∃ a b, p (a, b) :=
   ⟨fun ⟨⟨a, b⟩, h⟩ => ⟨a, b, h⟩, fun ⟨a, b, h⟩ => ⟨⟨a, b⟩, h⟩⟩
 #align prod.exists Prod.exists
 
-/- warning: prod.forall' -> Prod.forall' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : α -> β -> Prop}, Iff (forall (x : Prod.{u1, u2} α β), p (Prod.fst.{u1, u2} α β x) (Prod.snd.{u1, u2} α β x)) (forall (a : α) (b : β), p a b)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : α -> β -> Prop}, Iff (forall (x : Prod.{u2, u1} α β), p (Prod.fst.{u2, u1} α β x) (Prod.snd.{u2, u1} α β x)) (forall (a : α) (b : β), p a b)
-Case conversion may be inaccurate. Consider using '#align prod.forall' Prod.forall'ₓ'. -/
 theorem forall' {p : α → β → Prop} : (∀ x : α × β, p x.1 x.2) ↔ ∀ a b, p a b :=
   Prod.forall
 #align prod.forall' Prod.forall'
 
-/- warning: prod.exists' -> Prod.exists' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : α -> β -> Prop}, Iff (Exists.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => p (Prod.fst.{u1, u2} α β x) (Prod.snd.{u1, u2} α β x))) (Exists.{succ u1} α (fun (a : α) => Exists.{succ u2} β (fun (b : β) => p a b)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : α -> β -> Prop}, Iff (Exists.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => p (Prod.fst.{u2, u1} α β x) (Prod.snd.{u2, u1} α β x))) (Exists.{succ u2} α (fun (a : α) => Exists.{succ u1} β (fun (b : β) => p a b)))
-Case conversion may be inaccurate. Consider using '#align prod.exists' Prod.exists'ₓ'. -/
 theorem exists' {p : α → β → Prop} : (∃ x : α × β, p x.1 x.2) ↔ ∃ a b, p a b :=
   Prod.exists
 #align prod.exists' Prod.exists'
@@ -85,74 +55,32 @@ theorem snd_comp_mk (x : α) : Prod.snd ∘ (Prod.mk x : β → α × β) = id :
 #align prod.snd_comp_mk Prod.snd_comp_mk
 -/
 
-/- warning: prod.fst_comp_mk -> Prod.fst_comp_mk is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (x : α), Eq.{max (succ u2) (succ u1)} (β -> α) (Function.comp.{succ u2, max (succ u1) (succ u2), succ u1} β (Prod.{u1, u2} α β) α (Prod.fst.{u1, u2} α β) (Prod.mk.{u1, u2} α β x)) (Function.const.{succ u1, succ u2} α β x)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (x : α), Eq.{max (succ u2) (succ u1)} (β -> α) (Function.comp.{succ u1, max (succ u1) (succ u2), succ u2} β (Prod.{u2, u1} α β) α (Prod.fst.{u2, u1} α β) (Prod.mk.{u2, u1} α β x)) (Function.const.{succ u2, succ u1} α β x)
-Case conversion may be inaccurate. Consider using '#align prod.fst_comp_mk Prod.fst_comp_mkₓ'. -/
 @[simp]
 theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Function.const β x :=
   rfl
 #align prod.fst_comp_mk Prod.fst_comp_mk
 
-/- warning: prod.map_mk -> Prod.map_mk is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ) (a : α) (b : β), Eq.{max (succ u3) (succ u4)} (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g (Prod.mk.{u1, u2} α β a b)) (Prod.mk.{u3, u4} γ δ (f a) (g b))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {γ : Type.{u4}} {δ : Type.{u3}} (f : α -> γ) (g : β -> δ) (a : α) (b : β), Eq.{max (succ u4) (succ u3)} (Prod.{u4, u3} γ δ) (Prod.map.{u2, u4, u1, u3} α γ β δ f g (Prod.mk.{u2, u1} α β a b)) (Prod.mk.{u4, u3} γ δ (f a) (g b))
-Case conversion may be inaccurate. Consider using '#align prod.map_mk Prod.map_mkₓ'. -/
 @[simp]
 theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) :=
   rfl
 #align prod.map_mk Prod.map_mk
 
-/- warning: prod.map_fst -> Prod.map_fst is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ) (p : Prod.{u1, u2} α β), Eq.{succ u3} γ (Prod.fst.{u3, u4} γ δ (Prod.map.{u1, u3, u2, u4} α γ β δ f g p)) (f (Prod.fst.{u1, u2} α β p))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u2}} {δ : Type.{u1}} (f : α -> γ) (g : β -> δ) (p : Prod.{u4, u3} α β), Eq.{succ u2} γ (Prod.fst.{u2, u1} γ δ (Prod.map.{u4, u2, u3, u1} α γ β δ f g p)) (f (Prod.fst.{u4, u3} α β p))
-Case conversion may be inaccurate. Consider using '#align prod.map_fst Prod.map_fstₓ'. -/
 theorem map_fst (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).1 = f p.1 :=
   rfl
 #align prod.map_fst Prod.map_fst
 
-/- warning: prod.map_snd -> Prod.map_snd is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ) (p : Prod.{u1, u2} α β), Eq.{succ u4} δ (Prod.snd.{u3, u4} γ δ (Prod.map.{u1, u3, u2, u4} α γ β δ f g p)) (g (Prod.snd.{u1, u2} α β p))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} (f : α -> γ) (g : β -> δ) (p : Prod.{u4, u3} α β), Eq.{succ u2} δ (Prod.snd.{u1, u2} γ δ (Prod.map.{u4, u1, u3, u2} α γ β δ f g p)) (g (Prod.snd.{u4, u3} α β p))
-Case conversion may be inaccurate. Consider using '#align prod.map_snd Prod.map_sndₓ'. -/
 theorem map_snd (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).2 = g p.2 :=
   rfl
 #align prod.map_snd Prod.map_snd
 
-/- warning: prod.map_fst' -> Prod.map_fst' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ), Eq.{max (max (succ u1) (succ u2)) (succ u3)} ((Prod.{u1, u2} α β) -> γ) (Function.comp.{max (succ u1) (succ u2), max (succ u3) (succ u4), succ u3} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) γ (Prod.fst.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (Function.comp.{max (succ u1) (succ u2), succ u1, succ u3} (Prod.{u1, u2} α β) α γ f (Prod.fst.{u1, u2} α β))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u2}} {δ : Type.{u1}} (f : α -> γ) (g : β -> δ), Eq.{max (max (succ u4) (succ u3)) (succ u2)} ((Prod.{u4, u3} α β) -> γ) (Function.comp.{max (succ u3) (succ u4), max (succ u1) (succ u2), succ u2} (Prod.{u4, u3} α β) (Prod.{u2, u1} γ δ) γ (Prod.fst.{u2, u1} γ δ) (Prod.map.{u4, u2, u3, u1} α γ β δ f g)) (Function.comp.{max (succ u3) (succ u4), succ u4, succ u2} (Prod.{u4, u3} α β) α γ f (Prod.fst.{u4, u3} α β))
-Case conversion may be inaccurate. Consider using '#align prod.map_fst' Prod.map_fst'ₓ'. -/
 theorem map_fst' (f : α → γ) (g : β → δ) : Prod.fst ∘ map f g = f ∘ Prod.fst :=
   funext <| map_fst f g
 #align prod.map_fst' Prod.map_fst'
 
-/- warning: prod.map_snd' -> Prod.map_snd' is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} (f : α -> γ) (g : β -> δ), Eq.{max (max (succ u1) (succ u2)) (succ u4)} ((Prod.{u1, u2} α β) -> δ) (Function.comp.{max (succ u1) (succ u2), max (succ u3) (succ u4), succ u4} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) δ (Prod.snd.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (Function.comp.{max (succ u1) (succ u2), succ u2, succ u4} (Prod.{u1, u2} α β) β δ g (Prod.snd.{u1, u2} α β))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} (f : α -> γ) (g : β -> δ), Eq.{max (max (succ u4) (succ u3)) (succ u2)} ((Prod.{u4, u3} α β) -> δ) (Function.comp.{max (succ u3) (succ u4), max (succ u2) (succ u1), succ u2} (Prod.{u4, u3} α β) (Prod.{u1, u2} γ δ) δ (Prod.snd.{u1, u2} γ δ) (Prod.map.{u4, u1, u3, u2} α γ β δ f g)) (Function.comp.{max (succ u3) (succ u4), succ u3, succ u2} (Prod.{u4, u3} α β) β δ g (Prod.snd.{u4, u3} α β))
-Case conversion may be inaccurate. Consider using '#align prod.map_snd' Prod.map_snd'ₓ'. -/
 theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘ Prod.snd :=
   funext <| map_snd f g
 #align prod.map_snd' Prod.map_snd'
 
-/- warning: prod.map_comp_map -> Prod.map_comp_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {ε : Type.{u5}} {ζ : Type.{u6}} (f : α -> β) (f' : γ -> δ) (g : β -> ε) (g' : δ -> ζ), Eq.{max (max (succ u1) (succ u3)) (succ u5) (succ u6)} ((Prod.{u1, u3} α γ) -> (Prod.{u5, u6} ε ζ)) (Function.comp.{max (succ u1) (succ u3), max (succ u2) (succ u4), max (succ u5) (succ u6)} (Prod.{u1, u3} α γ) (Prod.{u2, u4} β δ) (Prod.{u5, u6} ε ζ) (Prod.map.{u2, u5, u4, u6} β ε δ ζ g g') (Prod.map.{u1, u2, u3, u4} α β γ δ f f')) (Prod.map.{u1, u5, u3, u6} α ε γ ζ (Function.comp.{succ u1, succ u2, succ u5} α β ε g f) (Function.comp.{succ u3, succ u4, succ u6} γ δ ζ g' f'))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u1}} {γ : Type.{u3}} {δ : Type.{u2}} {ε : Type.{u6}} {ζ : Type.{u5}} (f : α -> β) (f' : γ -> δ) (g : β -> ε) (g' : δ -> ζ), Eq.{max (max (max (succ u4) (succ u3)) (succ u6)) (succ u5)} ((Prod.{u4, u3} α γ) -> (Prod.{u6, u5} ε ζ)) (Function.comp.{max (succ u3) (succ u4), max (succ u2) (succ u1), max (succ u5) (succ u6)} (Prod.{u4, u3} α γ) (Prod.{u1, u2} β δ) (Prod.{u6, u5} ε ζ) (Prod.map.{u1, u6, u2, u5} β ε δ ζ g g') (Prod.map.{u4, u1, u3, u2} α β γ δ f f')) (Prod.map.{u4, u6, u3, u5} α ε γ ζ (Function.comp.{succ u4, succ u1, succ u6} α β ε g f) (Function.comp.{succ u3, succ u2, succ u5} γ δ ζ g' f'))
-Case conversion may be inaccurate. Consider using '#align prod.map_comp_map Prod.map_comp_mapₓ'. -/
 /-- Composing a `prod.map` with another `prod.map` is equal to
 a single `prod.map` of composed functions.
 -/
@@ -161,12 +89,6 @@ theorem map_comp_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β 
   rfl
 #align prod.map_comp_map Prod.map_comp_map
 
-/- warning: prod.map_map -> Prod.map_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {ε : Type.{u5}} {ζ : Type.{u6}} (f : α -> β) (f' : γ -> δ) (g : β -> ε) (g' : δ -> ζ) (x : Prod.{u1, u3} α γ), Eq.{max (succ u5) (succ u6)} (Prod.{u5, u6} ε ζ) (Prod.map.{u2, u5, u4, u6} β ε δ ζ g g' (Prod.map.{u1, u2, u3, u4} α β γ δ f f' x)) (Prod.map.{u1, u5, u3, u6} α ε γ ζ (Function.comp.{succ u1, succ u2, succ u5} α β ε g f) (Function.comp.{succ u3, succ u4, succ u6} γ δ ζ g' f') x)
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u1}} {ε : Type.{u6}} {ζ : Type.{u5}} (f : α -> β) (f' : γ -> δ) (g : β -> ε) (g' : δ -> ζ) (x : Prod.{u4, u3} α γ), Eq.{max (succ u6) (succ u5)} (Prod.{u6, u5} ε ζ) (Prod.map.{u2, u6, u1, u5} β ε δ ζ g g' (Prod.map.{u4, u2, u3, u1} α β γ δ f f' x)) (Prod.map.{u4, u6, u3, u5} α ε γ ζ (Function.comp.{succ u4, succ u2, succ u6} α β ε g f) (Function.comp.{succ u3, succ u1, succ u5} γ δ ζ g' f') x)
-Case conversion may be inaccurate. Consider using '#align prod.map_map Prod.map_mapₓ'. -/
 /-- Composing a `prod.map` with another `prod.map` is equal to
 a single `prod.map` of composed functions, fully applied.
 -/
@@ -177,105 +99,45 @@ theorem map_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε
 
 variable {a a₁ a₂ : α} {b b₁ b₂ : β}
 
-/- warning: prod.mk.inj_iff -> Prod.mk.inj_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.mk.{u1, u2} α β a₁ b₁) (Prod.mk.{u1, u2} α β a₂ b₂)) (And (Eq.{succ u1} α a₁ a₂) (Eq.{succ u2} β b₁ b₂))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.mk.{u2, u1} α β a₁ b₁) (Prod.mk.{u2, u1} α β a₂ b₂)) (And (Eq.{succ u2} α a₁ a₂) (Eq.{succ u1} β b₁ b₂))
-Case conversion may be inaccurate. Consider using '#align prod.mk.inj_iff Prod.mk.inj_iffₓ'. -/
 @[simp]
 theorem mk.inj_iff : (a₁, b₁) = (a₂, b₂) ↔ a₁ = a₂ ∧ b₁ = b₂ :=
   ⟨Prod.mk.inj, by cc⟩
 #align prod.mk.inj_iff Prod.mk.inj_iff
 
-/- warning: prod.mk.inj_left -> Prod.mk.inj_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (a : α), Function.Injective.{succ u2, max (succ u1) (succ u2)} β (Prod.{u1, u2} α β) (Prod.mk.{u1, u2} α β a)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (a : α), Function.Injective.{succ u1, max (succ u2) (succ u1)} β (Prod.{u2, u1} α β) (Prod.mk.{u2, u1} α β a)
-Case conversion may be inaccurate. Consider using '#align prod.mk.inj_left Prod.mk.inj_leftₓ'. -/
 theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
   intro b₁ b₂ h; simpa only [true_and_iff, Prod.mk.inj_iff, eq_self_iff_true] using h
 #align prod.mk.inj_left Prod.mk.inj_left
 
-/- warning: prod.mk.inj_right -> Prod.mk.inj_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (b : β), Function.Injective.{succ u1, max (succ u1) (succ u2)} α (Prod.{u1, u2} α β) (fun (a : α) => Prod.mk.{u1, u2} α β a b)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (b : β), Function.Injective.{succ u2, max (succ u2) (succ u1)} α (Prod.{u2, u1} α β) (fun (a : α) => Prod.mk.{u2, u1} α β a b)
-Case conversion may be inaccurate. Consider using '#align prod.mk.inj_right Prod.mk.inj_rightₓ'. -/
 theorem mk.inj_right {α β : Type _} (b : β) :
     Function.Injective (fun a => Prod.mk a b : α → α × β) := by intro b₁ b₂ h;
   · simpa only [and_true_iff, eq_self_iff_true, mk.inj_iff] using h
 #align prod.mk.inj_right Prod.mk.inj_right
 
-/- warning: prod.mk_inj_left -> Prod.mk_inj_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {a : α} {b₁ : β} {b₂ : β}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.mk.{u1, u2} α β a b₁) (Prod.mk.{u1, u2} α β a b₂)) (Eq.{succ u2} β b₁ b₂)
-but is expected to have type
-  forall {α : Type.{u2}} {β : α} {a : Type.{u1}} {b₁ : a} {b₂ : a}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u2, u1} α a) (Prod.mk.{u2, u1} α a β b₁) (Prod.mk.{u2, u1} α a β b₂)) (Eq.{succ u1} a b₁ b₂)
-Case conversion may be inaccurate. Consider using '#align prod.mk_inj_left Prod.mk_inj_leftₓ'. -/
 theorem mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ :=
   (mk.inj_left _).eq_iff
 #align prod.mk_inj_left Prod.mk_inj_left
 
-/- warning: prod.mk_inj_right -> Prod.mk_inj_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {a₁ : α} {a₂ : α} {b : β}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.mk.{u1, u2} α β a₁ b) (Prod.mk.{u1, u2} α β a₂ b)) (Eq.{succ u1} α a₁ a₂)
-but is expected to have type
-  forall {α : Type.{u2}} {β : α} {a₁ : Type.{u1}} {a₂ : a₁} {b : α}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u2, u1} α a₁) (Prod.mk.{u2, u1} α a₁ β a₂) (Prod.mk.{u2, u1} α a₁ b a₂)) (Eq.{succ u2} α β b)
-Case conversion may be inaccurate. Consider using '#align prod.mk_inj_right Prod.mk_inj_rightₓ'. -/
 theorem mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ :=
   (mk.inj_right _).eq_iff
 #align prod.mk_inj_right Prod.mk_inj_right
 
-/- warning: prod.ext_iff -> Prod.ext_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {q : Prod.{u1, u2} α β}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p q) (And (Eq.{succ u1} α (Prod.fst.{u1, u2} α β p) (Prod.fst.{u1, u2} α β q)) (Eq.{succ u2} β (Prod.snd.{u1, u2} α β p) (Prod.snd.{u1, u2} α β q)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {q : Prod.{u2, u1} α β}, Iff (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) p q) (And (Eq.{succ u2} α (Prod.fst.{u2, u1} α β p) (Prod.fst.{u2, u1} α β q)) (Eq.{succ u1} β (Prod.snd.{u2, u1} α β p) (Prod.snd.{u2, u1} α β q)))
-Case conversion may be inaccurate. Consider using '#align prod.ext_iff Prod.ext_iffₓ'. -/
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
   rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
 #align prod.ext_iff Prod.ext_iff
 
-/- warning: prod.ext -> Prod.ext is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {q : Prod.{u1, u2} α β}, (Eq.{succ u1} α (Prod.fst.{u1, u2} α β p) (Prod.fst.{u1, u2} α β q)) -> (Eq.{succ u2} β (Prod.snd.{u1, u2} α β p) (Prod.snd.{u1, u2} α β q)) -> (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p q)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {q : Prod.{u2, u1} α β}, (Eq.{succ u2} α (Prod.fst.{u2, u1} α β p) (Prod.fst.{u2, u1} α β q)) -> (Eq.{succ u1} β (Prod.snd.{u2, u1} α β p) (Prod.snd.{u2, u1} α β q)) -> (Eq.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) p q)
-Case conversion may be inaccurate. Consider using '#align prod.ext Prod.extₓ'. -/
 @[ext]
 theorem ext {α β} {p q : α × β} (h₁ : p.1 = q.1) (h₂ : p.2 = q.2) : p = q :=
   ext_iff.2 ⟨h₁, h₂⟩
 #align prod.ext Prod.ext
 
-/- warning: prod.map_def -> Prod.map_def is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f : α -> γ} {g : β -> δ}, Eq.{max (max (succ u1) (succ u2)) (succ u3) (succ u4)} ((Prod.{u1, u2} α β) -> (Prod.{u3, u4} γ δ)) (Prod.map.{u1, u3, u2, u4} α γ β δ f g) (fun (p : Prod.{u1, u2} α β) => Prod.mk.{u3, u4} γ δ (f (Prod.fst.{u1, u2} α β p)) (g (Prod.snd.{u1, u2} α β p)))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u2}} {δ : Type.{u1}} {f : α -> γ} {g : β -> δ}, Eq.{max (max (max (succ u4) (succ u3)) (succ u2)) (succ u1)} ((Prod.{u4, u3} α β) -> (Prod.{u2, u1} γ δ)) (Prod.map.{u4, u2, u3, u1} α γ β δ f g) (fun (p : Prod.{u4, u3} α β) => Prod.mk.{u2, u1} γ δ (f (Prod.fst.{u4, u3} α β p)) (g (Prod.snd.{u4, u3} α β p)))
-Case conversion may be inaccurate. Consider using '#align prod.map_def Prod.map_defₓ'. -/
 theorem map_def {f : α → γ} {g : β → δ} : Prod.map f g = fun p : α × β => (f p.1, g p.2) :=
   funext fun p => ext (map_fst f g p) (map_snd f g p)
 #align prod.map_def Prod.map_def
 
-/- warning: prod.id_prod -> Prod.id_prod is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Eq.{max (succ u1) (succ u2)} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β)) (fun (p : Prod.{u1, u2} α β) => Prod.mk.{u1, u2} α β (Prod.fst.{u1, u2} α β p) (Prod.snd.{u1, u2} α β p)) (id.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Eq.{max (succ u2) (succ u1)} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β)) (fun (p : Prod.{u2, u1} α β) => Prod.mk.{u2, u1} α β (Prod.fst.{u2, u1} α β p) (Prod.snd.{u2, u1} α β p)) (id.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β))
-Case conversion may be inaccurate. Consider using '#align prod.id_prod Prod.id_prodₓ'. -/
 theorem id_prod : (fun p : α × β => (p.1, p.2)) = id :=
   funext fun ⟨a, b⟩ => rfl
 #align prod.id_prod Prod.id_prod
 
-/- warning: prod.map_id -> Prod.map_id is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Eq.{max (succ u1) (succ u2)} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β)) (Prod.map.{u1, u1, u2, u2} α α β β (id.{succ u1} α) (id.{succ u2} β)) (id.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Eq.{max (succ u2) (succ u1)} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β)) (Prod.map.{u2, u2, u1, u1} α α β β (id.{succ u2} α) (id.{succ u1} β)) (id.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β))
-Case conversion may be inaccurate. Consider using '#align prod.map_id Prod.map_idₓ'. -/
 theorem map_id : Prod.map (@id α) (@id β) = id :=
   id_prod
 #align prod.map_id Prod.map_id
@@ -286,12 +148,6 @@ theorem fst_surjective [h : Nonempty β] : Function.Surjective (@fst α β) := f
 #align prod.fst_surjective Prod.fst_surjective
 -/
 
-/- warning: prod.snd_surjective -> Prod.snd_surjective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [h : Nonempty.{succ u1} α], Function.Surjective.{max (succ u1) (succ u2), succ u2} (Prod.{u1, u2} α β) β (Prod.snd.{u1, u2} α β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [h : Nonempty.{succ u2} α], Function.Surjective.{max (succ u2) (succ u1), succ u1} (Prod.{u2, u1} α β) β (Prod.snd.{u2, u1} α β)
-Case conversion may be inaccurate. Consider using '#align prod.snd_surjective Prod.snd_surjectiveₓ'. -/
 theorem snd_surjective [h : Nonempty α] : Function.Surjective (@snd α β) := fun y =>
   h.elim fun x => ⟨⟨x, y⟩, rfl⟩
 #align prod.snd_surjective Prod.snd_surjective
@@ -302,12 +158,6 @@ theorem fst_injective [Subsingleton β] : Function.Injective (@fst α β) := fun
 #align prod.fst_injective Prod.fst_injective
 -/
 
-/- warning: prod.snd_injective -> Prod.snd_injective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : Subsingleton.{succ u1} α], Function.Injective.{max (succ u1) (succ u2), succ u2} (Prod.{u1, u2} α β) β (Prod.snd.{u1, u2} α β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : Subsingleton.{succ u2} α], Function.Injective.{max (succ u2) (succ u1), succ u1} (Prod.{u2, u1} α β) β (Prod.snd.{u2, u1} α β)
-Case conversion may be inaccurate. Consider using '#align prod.snd_injective Prod.snd_injectiveₓ'. -/
 theorem snd_injective [Subsingleton α] : Function.Injective (@snd α β) := fun x y h =>
   ext (Subsingleton.elim _ _) h
 #align prod.snd_injective Prod.snd_injective
@@ -318,162 +168,72 @@ def swap : α × β → β × α := fun p => (p.2, p.1)
 #align prod.swap Prod.swap
 -/
 
-/- warning: prod.swap_swap -> Prod.swap_swap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (x : Prod.{u1, u2} α β), Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.swap.{u2, u1} β α (Prod.swap.{u1, u2} α β x)) x
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (x : Prod.{u2, u1} α β), Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.swap.{u1, u2} β α (Prod.swap.{u2, u1} α β x)) x
-Case conversion may be inaccurate. Consider using '#align prod.swap_swap Prod.swap_swapₓ'. -/
 @[simp]
 theorem swap_swap : ∀ x : α × β, swap (swap x) = x
   | ⟨a, b⟩ => rfl
 #align prod.swap_swap Prod.swap_swap
 
-/- warning: prod.fst_swap -> Prod.fst_swap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β}, Eq.{succ u2} β (Prod.fst.{u2, u1} β α (Prod.swap.{u1, u2} α β p)) (Prod.snd.{u1, u2} α β p)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β}, Eq.{succ u1} β (Prod.fst.{u1, u2} β α (Prod.swap.{u2, u1} α β p)) (Prod.snd.{u2, u1} α β p)
-Case conversion may be inaccurate. Consider using '#align prod.fst_swap Prod.fst_swapₓ'. -/
 @[simp]
 theorem fst_swap {p : α × β} : (swap p).1 = p.2 :=
   rfl
 #align prod.fst_swap Prod.fst_swap
 
-/- warning: prod.snd_swap -> Prod.snd_swap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β}, Eq.{succ u1} α (Prod.snd.{u2, u1} β α (Prod.swap.{u1, u2} α β p)) (Prod.fst.{u1, u2} α β p)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β}, Eq.{succ u2} α (Prod.snd.{u1, u2} β α (Prod.swap.{u2, u1} α β p)) (Prod.fst.{u2, u1} α β p)
-Case conversion may be inaccurate. Consider using '#align prod.snd_swap Prod.snd_swapₓ'. -/
 @[simp]
 theorem snd_swap {p : α × β} : (swap p).2 = p.1 :=
   rfl
 #align prod.snd_swap Prod.snd_swap
 
-/- warning: prod.swap_prod_mk -> Prod.swap_prod_mk is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {a : α} {b : β}, Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} β α) (Prod.swap.{u1, u2} α β (Prod.mk.{u1, u2} α β a b)) (Prod.mk.{u2, u1} β α b a)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {a : α} {b : β}, Eq.{max (succ u2) (succ u1)} (Prod.{u1, u2} β α) (Prod.swap.{u2, u1} α β (Prod.mk.{u2, u1} α β a b)) (Prod.mk.{u1, u2} β α b a)
-Case conversion may be inaccurate. Consider using '#align prod.swap_prod_mk Prod.swap_prod_mkₓ'. -/
 @[simp]
 theorem swap_prod_mk {a : α} {b : β} : swap (a, b) = (b, a) :=
   rfl
 #align prod.swap_prod_mk Prod.swap_prod_mk
 
-/- warning: prod.swap_swap_eq -> Prod.swap_swap_eq is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Eq.{max (succ u1) (succ u2)} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β)) (Function.comp.{max (succ u1) (succ u2), max (succ u2) (succ u1), max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (Prod.swap.{u2, u1} β α) (Prod.swap.{u1, u2} α β)) (id.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Eq.{max (succ u2) (succ u1)} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β)) (Function.comp.{max (succ u1) (succ u2), max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.{u1, u2} β α) (Prod.{u2, u1} α β) (Prod.swap.{u1, u2} β α) (Prod.swap.{u2, u1} α β)) (id.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β))
-Case conversion may be inaccurate. Consider using '#align prod.swap_swap_eq Prod.swap_swap_eqₓ'. -/
 @[simp]
 theorem swap_swap_eq : swap ∘ swap = @id (α × β) :=
   funext swap_swap
 #align prod.swap_swap_eq Prod.swap_swap_eq
 
-/- warning: prod.swap_left_inverse -> Prod.swap_leftInverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Function.LeftInverse.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (Prod.swap.{u1, u2} α β) (Prod.swap.{u2, u1} β α)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Function.LeftInverse.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u1, u2} β α) (Prod.{u2, u1} α β) (Prod.swap.{u2, u1} α β) (Prod.swap.{u1, u2} β α)
-Case conversion may be inaccurate. Consider using '#align prod.swap_left_inverse Prod.swap_leftInverseₓ'. -/
 @[simp]
 theorem swap_leftInverse : Function.LeftInverse (@swap α β) swap :=
   swap_swap
 #align prod.swap_left_inverse Prod.swap_leftInverse
 
-/- warning: prod.swap_right_inverse -> Prod.swap_rightInverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Function.RightInverse.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (Prod.swap.{u1, u2} α β) (Prod.swap.{u2, u1} β α)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Function.RightInverse.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u1, u2} β α) (Prod.{u2, u1} α β) (Prod.swap.{u2, u1} α β) (Prod.swap.{u1, u2} β α)
-Case conversion may be inaccurate. Consider using '#align prod.swap_right_inverse Prod.swap_rightInverseₓ'. -/
 @[simp]
 theorem swap_rightInverse : Function.RightInverse (@swap α β) swap :=
   swap_swap
 #align prod.swap_right_inverse Prod.swap_rightInverse
 
-/- warning: prod.swap_injective -> Prod.swap_injective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Function.Injective.{max (succ u1) (succ u2), max (succ u2) (succ u1)} (Prod.{u1, u2} α β) (Prod.{u2, u1} β α) (Prod.swap.{u1, u2} α β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Function.Injective.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.{u1, u2} β α) (Prod.swap.{u2, u1} α β)
-Case conversion may be inaccurate. Consider using '#align prod.swap_injective Prod.swap_injectiveₓ'. -/
 theorem swap_injective : Function.Injective (@swap α β) :=
   swap_leftInverse.Injective
 #align prod.swap_injective Prod.swap_injective
 
-/- warning: prod.swap_surjective -> Prod.swap_surjective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Function.Surjective.{max (succ u1) (succ u2), max (succ u2) (succ u1)} (Prod.{u1, u2} α β) (Prod.{u2, u1} β α) (Prod.swap.{u1, u2} α β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Function.Surjective.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.{u1, u2} β α) (Prod.swap.{u2, u1} α β)
-Case conversion may be inaccurate. Consider using '#align prod.swap_surjective Prod.swap_surjectiveₓ'. -/
 theorem swap_surjective : Function.Surjective (@swap α β) :=
   swap_leftInverse.Surjective
 #align prod.swap_surjective Prod.swap_surjective
 
-/- warning: prod.swap_bijective -> Prod.swap_bijective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}}, Function.Bijective.{max (succ u1) (succ u2), max (succ u2) (succ u1)} (Prod.{u1, u2} α β) (Prod.{u2, u1} β α) (Prod.swap.{u1, u2} α β)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}}, Function.Bijective.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (Prod.{u2, u1} α β) (Prod.{u1, u2} β α) (Prod.swap.{u2, u1} α β)
-Case conversion may be inaccurate. Consider using '#align prod.swap_bijective Prod.swap_bijectiveₓ'. -/
 theorem swap_bijective : Function.Bijective (@swap α β) :=
   ⟨swap_injective, swap_surjective⟩
 #align prod.swap_bijective Prod.swap_bijective
 
-/- warning: prod.swap_inj -> Prod.swap_inj is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {q : Prod.{u1, u2} α β}, Iff (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} β α) (Prod.swap.{u1, u2} α β p) (Prod.swap.{u1, u2} α β q)) (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p q)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {q : Prod.{u2, u1} α β}, Iff (Eq.{max (succ u2) (succ u1)} (Prod.{u1, u2} β α) (Prod.swap.{u2, u1} α β p) (Prod.swap.{u2, u1} α β q)) (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) p q)
-Case conversion may be inaccurate. Consider using '#align prod.swap_inj Prod.swap_injₓ'. -/
 @[simp]
 theorem swap_inj {p q : α × β} : swap p = swap q ↔ p = q :=
   swap_injective.eq_iff
 #align prod.swap_inj Prod.swap_inj
 
-/- warning: prod.eq_iff_fst_eq_snd_eq -> Prod.eq_iff_fst_eq_snd_eq is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {q : Prod.{u1, u2} α β}, Iff (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p q) (And (Eq.{succ u1} α (Prod.fst.{u1, u2} α β p) (Prod.fst.{u1, u2} α β q)) (Eq.{succ u2} β (Prod.snd.{u1, u2} α β p) (Prod.snd.{u1, u2} α β q)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {q : Prod.{u2, u1} α β}, Iff (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) p q) (And (Eq.{succ u2} α (Prod.fst.{u2, u1} α β p) (Prod.fst.{u2, u1} α β q)) (Eq.{succ u1} β (Prod.snd.{u2, u1} α β p) (Prod.snd.{u2, u1} α β q)))
-Case conversion may be inaccurate. Consider using '#align prod.eq_iff_fst_eq_snd_eq Prod.eq_iff_fst_eq_snd_eqₓ'. -/
 theorem eq_iff_fst_eq_snd_eq : ∀ {p q : α × β}, p = q ↔ p.1 = q.1 ∧ p.2 = q.2
   | ⟨p₁, p₂⟩, ⟨q₁, q₂⟩ => by simp
 #align prod.eq_iff_fst_eq_snd_eq Prod.eq_iff_fst_eq_snd_eq
 
-/- warning: prod.fst_eq_iff -> Prod.fst_eq_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {x : α}, Iff (Eq.{succ u1} α (Prod.fst.{u1, u2} α β p) x) (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p (Prod.mk.{u1, u2} α β x (Prod.snd.{u1, u2} α β p)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {x : α}, Iff (Eq.{succ u2} α (Prod.fst.{u2, u1} α β p) x) (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) p (Prod.mk.{u2, u1} α β x (Prod.snd.{u2, u1} α β p)))
-Case conversion may be inaccurate. Consider using '#align prod.fst_eq_iff Prod.fst_eq_iffₓ'. -/
 theorem fst_eq_iff : ∀ {p : α × β} {x : α}, p.1 = x ↔ p = (x, p.2)
   | ⟨a, b⟩, x => by simp
 #align prod.fst_eq_iff Prod.fst_eq_iff
 
-/- warning: prod.snd_eq_iff -> Prod.snd_eq_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {p : Prod.{u1, u2} α β} {x : β}, Iff (Eq.{succ u2} β (Prod.snd.{u1, u2} α β p) x) (Eq.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) p (Prod.mk.{u1, u2} α β (Prod.fst.{u1, u2} α β p) x))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {p : Prod.{u2, u1} α β} {x : β}, Iff (Eq.{succ u1} β (Prod.snd.{u2, u1} α β p) x) (Eq.{max (succ u2) (succ u1)} (Prod.{u2, u1} α β) p (Prod.mk.{u2, u1} α β (Prod.fst.{u2, u1} α β p) x))
-Case conversion may be inaccurate. Consider using '#align prod.snd_eq_iff Prod.snd_eq_iffₓ'. -/
 theorem snd_eq_iff : ∀ {p : α × β} {x : β}, p.2 = x ↔ p = (p.1, x)
   | ⟨a, b⟩, x => by simp
 #align prod.snd_eq_iff Prod.snd_eq_iff
 
 variable {r : α → α → Prop} {s : β → β → Prop} {x y : α × β}
 
-/- warning: prod.lex_def -> Prod.lex_def is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (r : α -> α -> Prop) (s : β -> β -> Prop) {p : Prod.{u1, u2} α β} {q : Prod.{u1, u2} α β}, Iff (Prod.Lex.{u1, u2} α β r s p q) (Or (r (Prod.fst.{u1, u2} α β p) (Prod.fst.{u1, u2} α β q)) (And (Eq.{succ u1} α (Prod.fst.{u1, u2} α β p) (Prod.fst.{u1, u2} α β q)) (s (Prod.snd.{u1, u2} α β p) (Prod.snd.{u1, u2} α β q))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (r : α -> α -> Prop) (s : β -> β -> Prop) {p : Prod.{u2, u1} α β} {q : Prod.{u2, u1} α β}, Iff (Prod.Lex.{u2, u1} α β r s p q) (Or (r (Prod.fst.{u2, u1} α β p) (Prod.fst.{u2, u1} α β q)) (And (Eq.{succ u2} α (Prod.fst.{u2, u1} α β p) (Prod.fst.{u2, u1} α β q)) (s (Prod.snd.{u2, u1} α β p) (Prod.snd.{u2, u1} α β q))))
-Case conversion may be inaccurate. Consider using '#align prod.lex_def Prod.lex_defₓ'. -/
 theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × β} :
     Prod.Lex r s p q ↔ r p.1 q.1 ∨ p.1 = q.1 ∧ s p.2 q.2 :=
   ⟨fun h => by cases h <;> simp [*], fun h =>
@@ -482,12 +242,6 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × 
     | (a, b), (c, d), Or.inr ⟨e, h⟩ => by change a = c at e <;> subst e <;> exact lex.right _ h⟩
 #align prod.lex_def Prod.lex_def
 
-/- warning: prod.lex_iff -> Prod.lex_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {r : α -> α -> Prop} {s : β -> β -> Prop} {x : Prod.{u1, u2} α β} {y : Prod.{u1, u2} α β}, Iff (Prod.Lex.{u1, u2} α β r s x y) (Or (r (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y)) (And (Eq.{succ u1} α (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y)) (s (Prod.snd.{u1, u2} α β x) (Prod.snd.{u1, u2} α β y))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {r : α -> α -> Prop} {s : β -> β -> Prop} {x : Prod.{u2, u1} α β} {y : Prod.{u2, u1} α β}, Iff (Prod.Lex.{u2, u1} α β r s x y) (Or (r (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y)) (And (Eq.{succ u2} α (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y)) (s (Prod.snd.{u2, u1} α β x) (Prod.snd.{u2, u1} α β y))))
-Case conversion may be inaccurate. Consider using '#align prod.lex_iff Prod.lex_iffₓ'. -/
 theorem lex_iff : Lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 :=
   lex_def _ _
 #align prod.lex_iff Prod.lex_iff
@@ -499,12 +253,6 @@ instance Lex.decidable [DecidableEq α] (r : α → α → Prop) (s : β → β
 #align prod.lex.decidable Prod.Lex.decidable
 -/
 
-/- warning: prod.lex.refl_left -> Prod.Lex.refl_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (r : α -> α -> Prop) (s : β -> β -> Prop) [_inst_1 : IsRefl.{u1} α r] (x : Prod.{u1, u2} α β), Prod.Lex.{u1, u2} α β r s x x
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (r : α -> α -> Prop) (s : β -> β -> Prop) [_inst_1 : IsRefl.{u2} α r] (x : Prod.{u2, u1} α β), Prod.Lex.{u2, u1} α β r s x x
-Case conversion may be inaccurate. Consider using '#align prod.lex.refl_left Prod.Lex.refl_leftₓ'. -/
 @[refl]
 theorem Lex.refl_left (r : α → α → Prop) (s : β → β → Prop) [IsRefl α r] : ∀ x, Prod.Lex r s x x
   | (x₁, x₂) => Lex.left _ _ (refl _)
@@ -533,12 +281,6 @@ instance isIrrefl [IsIrrefl α r] [IsIrrefl β s] : IsIrrefl (α × β) (Lex r s
 #align prod.is_irrefl Prod.isIrrefl
 -/
 
-/- warning: prod.lex.trans -> Prod.Lex.trans is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {r : α -> α -> Prop} {s : β -> β -> Prop} [_inst_1 : IsTrans.{u1} α r] [_inst_2 : IsTrans.{u2} β s] {x : Prod.{u1, u2} α β} {y : Prod.{u1, u2} α β} {z : Prod.{u1, u2} α β}, (Prod.Lex.{u1, u2} α β r s x y) -> (Prod.Lex.{u1, u2} α β r s y z) -> (Prod.Lex.{u1, u2} α β r s x z)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {r : α -> α -> Prop} {s : β -> β -> Prop} [_inst_1 : IsTrans.{u2} α r] [_inst_2 : IsTrans.{u1} β s] {x : Prod.{u2, u1} α β} {y : Prod.{u2, u1} α β} {z : Prod.{u2, u1} α β}, (Prod.Lex.{u2, u1} α β r s x y) -> (Prod.Lex.{u2, u1} α β r s y z) -> (Prod.Lex.{u2, u1} α β r s x z)
-Case conversion may be inaccurate. Consider using '#align prod.lex.trans Prod.Lex.transₓ'. -/
 @[trans]
 theorem Lex.trans {r : α → α → Prop} {s : β → β → Prop} [IsTrans α r] [IsTrans β s] :
     ∀ {x y z : α × β}, Prod.Lex r s x y → Prod.Lex r s y z → Prod.Lex r s x z
@@ -598,22 +340,10 @@ namespace Function
 
 variable {f : α → γ} {g : β → δ} {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α} {g₂ : δ → γ}
 
-/- warning: function.injective.prod_map -> Function.Injective.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f : α -> γ} {g : β -> δ}, (Function.Injective.{succ u1, succ u3} α γ f) -> (Function.Injective.{succ u2, succ u4} β δ g) -> (Function.Injective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u1}} {f : α -> γ} {g : β -> δ}, (Function.Injective.{succ u4, succ u3} α γ f) -> (Function.Injective.{succ u2, succ u1} β δ g) -> (Function.Injective.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u4, u2} α β) (Prod.{u3, u1} γ δ) (Prod.map.{u4, u3, u2, u1} α γ β δ f g))
-Case conversion may be inaccurate. Consider using '#align function.injective.prod_map Function.Injective.Prod_mapₓ'. -/
 theorem Injective.Prod_map (hf : Injective f) (hg : Injective g) : Injective (map f g) :=
   fun x y h => ext (hf (ext_iff.1 h).1) (hg <| (ext_iff.1 h).2)
 #align function.injective.prod_map Function.Injective.Prod_map
 
-/- warning: function.surjective.prod_map -> Function.Surjective.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f : α -> γ} {g : β -> δ}, (Function.Surjective.{succ u1, succ u3} α γ f) -> (Function.Surjective.{succ u2, succ u4} β δ g) -> (Function.Surjective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u1}} {f : α -> γ} {g : β -> δ}, (Function.Surjective.{succ u4, succ u3} α γ f) -> (Function.Surjective.{succ u2, succ u1} β δ g) -> (Function.Surjective.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u4, u2} α β) (Prod.{u3, u1} γ δ) (Prod.map.{u4, u3, u2, u1} α γ β δ f g))
-Case conversion may be inaccurate. Consider using '#align function.surjective.prod_map Function.Surjective.Prod_mapₓ'. -/
 theorem Surjective.Prod_map (hf : Surjective f) (hg : Surjective g) : Surjective (map f g) :=
   fun p =>
   let ⟨x, hx⟩ := hf p.1
@@ -621,44 +351,20 @@ theorem Surjective.Prod_map (hf : Surjective f) (hg : Surjective g) : Surjective
   ⟨(x, y), Prod.ext hx hy⟩
 #align function.surjective.prod_map Function.Surjective.Prod_map
 
-/- warning: function.bijective.prod_map -> Function.Bijective.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f : α -> γ} {g : β -> δ}, (Function.Bijective.{succ u1, succ u3} α γ f) -> (Function.Bijective.{succ u2, succ u4} β δ g) -> (Function.Bijective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u1}} {f : α -> γ} {g : β -> δ}, (Function.Bijective.{succ u4, succ u3} α γ f) -> (Function.Bijective.{succ u2, succ u1} β δ g) -> (Function.Bijective.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u4, u2} α β) (Prod.{u3, u1} γ δ) (Prod.map.{u4, u3, u2, u1} α γ β δ f g))
-Case conversion may be inaccurate. Consider using '#align function.bijective.prod_map Function.Bijective.Prod_mapₓ'. -/
 theorem Bijective.Prod_map (hf : Bijective f) (hg : Bijective g) : Bijective (map f g) :=
   ⟨hf.1.Prod_map hg.1, hf.2.Prod_map hg.2⟩
 #align function.bijective.prod_map Function.Bijective.Prod_map
 
-/- warning: function.left_inverse.prod_map -> Function.LeftInverse.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, (Function.LeftInverse.{succ u2, succ u1} β α f₁ f₂) -> (Function.LeftInverse.{succ u4, succ u3} δ γ g₁ g₂) -> (Function.LeftInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂))
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u4}} {γ : Type.{u1}} {δ : Type.{u2}} {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, (Function.LeftInverse.{succ u4, succ u3} β α f₁ f₂) -> (Function.LeftInverse.{succ u2, succ u1} δ γ g₁ g₂) -> (Function.LeftInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u4, u2} β δ) (Prod.{u3, u1} α γ) (Prod.map.{u3, u4, u1, u2} α β γ δ f₁ g₁) (Prod.map.{u4, u3, u2, u1} β α δ γ f₂ g₂))
-Case conversion may be inaccurate. Consider using '#align function.left_inverse.prod_map Function.LeftInverse.Prod_mapₓ'. -/
 theorem LeftInverse.Prod_map (hf : LeftInverse f₁ f₂) (hg : LeftInverse g₁ g₂) :
     LeftInverse (map f₁ g₁) (map f₂ g₂) := fun a => by
   rw [Prod.map_map, hf.comp_eq_id, hg.comp_eq_id, map_id, id]
 #align function.left_inverse.prod_map Function.LeftInverse.Prod_map
 
-/- warning: function.right_inverse.prod_map -> Function.RightInverse.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, (Function.RightInverse.{succ u2, succ u1} β α f₁ f₂) -> (Function.RightInverse.{succ u4, succ u3} δ γ g₁ g₂) -> (Function.RightInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂))
-but is expected to have type
-  forall {α : Type.{u3}} {β : Type.{u4}} {γ : Type.{u1}} {δ : Type.{u2}} {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, (Function.RightInverse.{succ u4, succ u3} β α f₁ f₂) -> (Function.RightInverse.{succ u2, succ u1} δ γ g₁ g₂) -> (Function.RightInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u4, u2} β δ) (Prod.{u3, u1} α γ) (Prod.map.{u3, u4, u1, u2} α β γ δ f₁ g₁) (Prod.map.{u4, u3, u2, u1} β α δ γ f₂ g₂))
-Case conversion may be inaccurate. Consider using '#align function.right_inverse.prod_map Function.RightInverse.Prod_mapₓ'. -/
 theorem RightInverse.Prod_map :
     RightInverse f₁ f₂ → RightInverse g₁ g₂ → RightInverse (map f₁ g₁) (map f₂ g₂) :=
   LeftInverse.Prod_map
 #align function.right_inverse.prod_map Function.RightInverse.Prod_map
 
-/- warning: function.involutive.prod_map -> Function.Involutive.Prod_map is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {f : α -> α} {g : β -> β}, (Function.Involutive.{succ u1} α f) -> (Function.Involutive.{succ u2} β g) -> (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.map.{u1, u1, u2, u2} α α β β f g))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {f : α -> α} {g : β -> β}, (Function.Involutive.{succ u2} α f) -> (Function.Involutive.{succ u1} β g) -> (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) (Prod.map.{u2, u2, u1, u1} α α β β f g))
-Case conversion may be inaccurate. Consider using '#align function.involutive.prod_map Function.Involutive.Prod_mapₓ'. -/
 theorem Involutive.Prod_map {f : α → α} {g : β → β} :
     Involutive f → Involutive g → Involutive (map f g) :=
   LeftInverse.Prod_map
@@ -670,12 +376,6 @@ namespace Prod
 
 open Function
 
-/- warning: prod.map_injective -> Prod.map_injective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Injective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Injective.{succ u1, succ u3} α γ f) (Function.Injective.{succ u2, succ u4} β δ g))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Injective.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} α β) (Prod.{u1, u2} γ δ) (Prod.map.{u4, u1, u3, u2} α γ β δ f g)) (And (Function.Injective.{succ u4, succ u1} α γ f) (Function.Injective.{succ u3, succ u2} β δ g))
-Case conversion may be inaccurate. Consider using '#align prod.map_injective Prod.map_injectiveₓ'. -/
 @[simp]
 theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Injective (map f g) ↔ Injective f ∧ Injective g :=
@@ -690,12 +390,6 @@ theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_injective Prod.map_injective
 
-/- warning: prod.map_surjective -> Prod.map_surjective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u3} γ] [_inst_2 : Nonempty.{succ u4} δ] {f : α -> γ} {g : β -> δ}, Iff (Function.Surjective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Surjective.{succ u1, succ u3} α γ f) (Function.Surjective.{succ u2, succ u4} β δ g))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u4}} {δ : Type.{u3}} [_inst_1 : Nonempty.{succ u4} γ] [_inst_2 : Nonempty.{succ u3} δ] {f : α -> γ} {g : β -> δ}, Iff (Function.Surjective.{max (succ u2) (succ u1), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u4, u3} γ δ) (Prod.map.{u1, u4, u2, u3} α γ β δ f g)) (And (Function.Surjective.{succ u1, succ u4} α γ f) (Function.Surjective.{succ u2, succ u3} β δ g))
-Case conversion may be inaccurate. Consider using '#align prod.map_surjective Prod.map_surjectiveₓ'. -/
 @[simp]
 theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → δ} :
     Surjective (map f g) ↔ Surjective f ∧ Surjective g :=
@@ -711,12 +405,6 @@ theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → 
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_surjective Prod.map_surjective
 
-/- warning: prod.map_bijective -> Prod.map_bijective is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Bijective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Bijective.{succ u1, succ u3} α γ f) (Function.Bijective.{succ u2, succ u4} β δ g))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Bijective.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} α β) (Prod.{u1, u2} γ δ) (Prod.map.{u4, u1, u3, u2} α γ β δ f g)) (And (Function.Bijective.{succ u4, succ u1} α γ f) (Function.Bijective.{succ u3, succ u2} β δ g))
-Case conversion may be inaccurate. Consider using '#align prod.map_bijective Prod.map_bijectiveₓ'. -/
 @[simp]
 theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Bijective (map f g) ↔ Bijective f ∧ Bijective g :=
@@ -726,12 +414,6 @@ theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
   exact (map_injective.and map_surjective).trans (and_and_and_comm _ _ _ _)
 #align prod.map_bijective Prod.map_bijective
 
-/- warning: prod.map_left_inverse -> Prod.map_leftInverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u2} β] [_inst_2 : Nonempty.{succ u4} δ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.LeftInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂)) (And (Function.LeftInverse.{succ u2, succ u1} β α f₁ f₂) (Function.LeftInverse.{succ u4, succ u3} δ γ g₁ g₂))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u4}} {γ : Type.{u2}} {δ : Type.{u3}} [_inst_1 : Nonempty.{succ u4} β] [_inst_2 : Nonempty.{succ u3} δ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.LeftInverse.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} β δ) (Prod.{u1, u2} α γ) (Prod.map.{u1, u4, u2, u3} α β γ δ f₁ g₁) (Prod.map.{u4, u1, u3, u2} β α δ γ f₂ g₂)) (And (Function.LeftInverse.{succ u4, succ u1} β α f₁ f₂) (Function.LeftInverse.{succ u3, succ u2} δ γ g₁ g₂))
-Case conversion may be inaccurate. Consider using '#align prod.map_left_inverse Prod.map_leftInverseₓ'. -/
 @[simp]
 theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : LeftInverse (map f₁ g₁) (map f₂ g₂) ↔ LeftInverse f₁ f₂ ∧ LeftInverse g₁ g₂ :=
@@ -745,24 +427,12 @@ theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : 
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_left_inverse Prod.map_leftInverse
 
-/- warning: prod.map_right_inverse -> Prod.map_rightInverse is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u3} γ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.RightInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂)) (And (Function.RightInverse.{succ u2, succ u1} β α f₁ f₂) (Function.RightInverse.{succ u4, succ u3} δ γ g₁ g₂))
-but is expected to have type
-  forall {α : Type.{u4}} {β : Type.{u1}} {γ : Type.{u3}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} γ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.RightInverse.{max (succ u2) (succ u1), max (succ u3) (succ u4)} (Prod.{u1, u2} β δ) (Prod.{u4, u3} α γ) (Prod.map.{u4, u1, u3, u2} α β γ δ f₁ g₁) (Prod.map.{u1, u4, u2, u3} β α δ γ f₂ g₂)) (And (Function.RightInverse.{succ u1, succ u4} β α f₁ f₂) (Function.RightInverse.{succ u2, succ u3} δ γ g₁ g₂))
-Case conversion may be inaccurate. Consider using '#align prod.map_right_inverse Prod.map_rightInverseₓ'. -/
 @[simp]
 theorem map_rightInverse [Nonempty α] [Nonempty γ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : RightInverse (map f₁ g₁) (map f₂ g₂) ↔ RightInverse f₁ f₂ ∧ RightInverse g₁ g₂ :=
   map_leftInverse
 #align prod.map_right_inverse Prod.map_rightInverse
 
-/- warning: prod.map_involutive -> Prod.map_involutive is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> α} {g : β -> β}, Iff (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.map.{u1, u1, u2, u2} α α β β f g)) (And (Function.Involutive.{succ u1} α f) (Function.Involutive.{succ u2} β g))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : Nonempty.{succ u2} α] [_inst_2 : Nonempty.{succ u1} β] {f : α -> α} {g : β -> β}, Iff (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) (Prod.map.{u2, u2, u1, u1} α α β β f g)) (And (Function.Involutive.{succ u2} α f) (Function.Involutive.{succ u1} β g))
-Case conversion may be inaccurate. Consider using '#align prod.map_involutive Prod.map_involutiveₓ'. -/
 @[simp]
 theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → β} :
     Involutive (map f g) ↔ Involutive f ∧ Involutive g :=
Diff
@@ -194,10 +194,8 @@ lean 3 declaration is
 but is expected to have type
   forall {α : Type.{u2}} {β : Type.{u1}} (a : α), Function.Injective.{succ u1, max (succ u2) (succ u1)} β (Prod.{u2, u1} α β) (Prod.mk.{u2, u1} α β a)
 Case conversion may be inaccurate. Consider using '#align prod.mk.inj_left Prod.mk.inj_leftₓ'. -/
-theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) :=
-  by
-  intro b₁ b₂ h
-  simpa only [true_and_iff, Prod.mk.inj_iff, eq_self_iff_true] using h
+theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
+  intro b₁ b₂ h; simpa only [true_and_iff, Prod.mk.inj_iff, eq_self_iff_true] using h
 #align prod.mk.inj_left Prod.mk.inj_left
 
 /- warning: prod.mk.inj_right -> Prod.mk.inj_right is a dubious translation:
@@ -207,9 +205,7 @@ but is expected to have type
   forall {α : Type.{u2}} {β : Type.{u1}} (b : β), Function.Injective.{succ u2, max (succ u2) (succ u1)} α (Prod.{u2, u1} α β) (fun (a : α) => Prod.mk.{u2, u1} α β a b)
 Case conversion may be inaccurate. Consider using '#align prod.mk.inj_right Prod.mk.inj_rightₓ'. -/
 theorem mk.inj_right {α β : Type _} (b : β) :
-    Function.Injective (fun a => Prod.mk a b : α → α × β) :=
-  by
-  intro b₁ b₂ h
+    Function.Injective (fun a => Prod.mk a b : α → α × β) := by intro b₁ b₂ h;
   · simpa only [and_true_iff, eq_self_iff_true, mk.inj_iff] using h
 #align prod.mk.inj_right Prod.mk.inj_right
 
Diff
@@ -674,6 +674,12 @@ namespace Prod
 
 open Function
 
+/- warning: prod.map_injective -> Prod.map_injective is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Injective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Injective.{succ u1, succ u3} α γ f) (Function.Injective.{succ u2, succ u4} β δ g))
+but is expected to have type
+  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Injective.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} α β) (Prod.{u1, u2} γ δ) (Prod.map.{u4, u1, u3, u2} α γ β δ f g)) (And (Function.Injective.{succ u4, succ u1} α γ f) (Function.Injective.{succ u3, succ u2} β δ g))
+Case conversion may be inaccurate. Consider using '#align prod.map_injective Prod.map_injectiveₓ'. -/
 @[simp]
 theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Injective (map f g) ↔ Injective f ∧ Injective g :=
@@ -688,6 +694,12 @@ theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_injective Prod.map_injective
 
+/- warning: prod.map_surjective -> Prod.map_surjective is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u3} γ] [_inst_2 : Nonempty.{succ u4} δ] {f : α -> γ} {g : β -> δ}, Iff (Function.Surjective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Surjective.{succ u1, succ u3} α γ f) (Function.Surjective.{succ u2, succ u4} β δ g))
+but is expected to have type
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u4}} {δ : Type.{u3}} [_inst_1 : Nonempty.{succ u4} γ] [_inst_2 : Nonempty.{succ u3} δ] {f : α -> γ} {g : β -> δ}, Iff (Function.Surjective.{max (succ u2) (succ u1), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u4, u3} γ δ) (Prod.map.{u1, u4, u2, u3} α γ β δ f g)) (And (Function.Surjective.{succ u1, succ u4} α γ f) (Function.Surjective.{succ u2, succ u3} β δ g))
+Case conversion may be inaccurate. Consider using '#align prod.map_surjective Prod.map_surjectiveₓ'. -/
 @[simp]
 theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → δ} :
     Surjective (map f g) ↔ Surjective f ∧ Surjective g :=
@@ -703,6 +715,12 @@ theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → 
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_surjective Prod.map_surjective
 
+/- warning: prod.map_bijective -> Prod.map_bijective is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Bijective.{max (succ u1) (succ u2), max (succ u3) (succ u4)} (Prod.{u1, u2} α β) (Prod.{u3, u4} γ δ) (Prod.map.{u1, u3, u2, u4} α γ β δ f g)) (And (Function.Bijective.{succ u1, succ u3} α γ f) (Function.Bijective.{succ u2, succ u4} β δ g))
+but is expected to have type
+  forall {α : Type.{u4}} {β : Type.{u3}} {γ : Type.{u1}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} β] {f : α -> γ} {g : β -> δ}, Iff (Function.Bijective.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} α β) (Prod.{u1, u2} γ δ) (Prod.map.{u4, u1, u3, u2} α γ β δ f g)) (And (Function.Bijective.{succ u4, succ u1} α γ f) (Function.Bijective.{succ u3, succ u2} β δ g))
+Case conversion may be inaccurate. Consider using '#align prod.map_bijective Prod.map_bijectiveₓ'. -/
 @[simp]
 theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
     Bijective (map f g) ↔ Bijective f ∧ Bijective g :=
@@ -712,6 +730,12 @@ theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
   exact (map_injective.and map_surjective).trans (and_and_and_comm _ _ _ _)
 #align prod.map_bijective Prod.map_bijective
 
+/- warning: prod.map_left_inverse -> Prod.map_leftInverse is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u2} β] [_inst_2 : Nonempty.{succ u4} δ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.LeftInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂)) (And (Function.LeftInverse.{succ u2, succ u1} β α f₁ f₂) (Function.LeftInverse.{succ u4, succ u3} δ γ g₁ g₂))
+but is expected to have type
+  forall {α : Type.{u1}} {β : Type.{u4}} {γ : Type.{u2}} {δ : Type.{u3}} [_inst_1 : Nonempty.{succ u4} β] [_inst_2 : Nonempty.{succ u3} δ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.LeftInverse.{max (succ u3) (succ u4), max (succ u2) (succ u1)} (Prod.{u4, u3} β δ) (Prod.{u1, u2} α γ) (Prod.map.{u1, u4, u2, u3} α β γ δ f₁ g₁) (Prod.map.{u4, u1, u3, u2} β α δ γ f₂ g₂)) (And (Function.LeftInverse.{succ u4, succ u1} β α f₁ f₂) (Function.LeftInverse.{succ u3, succ u2} δ γ g₁ g₂))
+Case conversion may be inaccurate. Consider using '#align prod.map_left_inverse Prod.map_leftInverseₓ'. -/
 @[simp]
 theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : LeftInverse (map f₁ g₁) (map f₂ g₂) ↔ LeftInverse f₁ f₂ ∧ LeftInverse g₁ g₂ :=
@@ -725,12 +749,24 @@ theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : 
     fun h => h.1.Prod_map h.2⟩
 #align prod.map_left_inverse Prod.map_leftInverse
 
+/- warning: prod.map_right_inverse -> Prod.map_rightInverse is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} {δ : Type.{u4}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u3} γ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.RightInverse.{max (succ u2) (succ u4), max (succ u1) (succ u3)} (Prod.{u2, u4} β δ) (Prod.{u1, u3} α γ) (Prod.map.{u1, u2, u3, u4} α β γ δ f₁ g₁) (Prod.map.{u2, u1, u4, u3} β α δ γ f₂ g₂)) (And (Function.RightInverse.{succ u2, succ u1} β α f₁ f₂) (Function.RightInverse.{succ u4, succ u3} δ γ g₁ g₂))
+but is expected to have type
+  forall {α : Type.{u4}} {β : Type.{u1}} {γ : Type.{u3}} {δ : Type.{u2}} [_inst_1 : Nonempty.{succ u4} α] [_inst_2 : Nonempty.{succ u3} γ] {f₁ : α -> β} {g₁ : γ -> δ} {f₂ : β -> α} {g₂ : δ -> γ}, Iff (Function.RightInverse.{max (succ u2) (succ u1), max (succ u3) (succ u4)} (Prod.{u1, u2} β δ) (Prod.{u4, u3} α γ) (Prod.map.{u4, u1, u3, u2} α β γ δ f₁ g₁) (Prod.map.{u1, u4, u2, u3} β α δ γ f₂ g₂)) (And (Function.RightInverse.{succ u1, succ u4} β α f₁ f₂) (Function.RightInverse.{succ u2, succ u3} δ γ g₁ g₂))
+Case conversion may be inaccurate. Consider using '#align prod.map_right_inverse Prod.map_rightInverseₓ'. -/
 @[simp]
 theorem map_rightInverse [Nonempty α] [Nonempty γ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
     {g₂ : δ → γ} : RightInverse (map f₁ g₁) (map f₂ g₂) ↔ RightInverse f₁ f₂ ∧ RightInverse g₁ g₂ :=
   map_leftInverse
 #align prod.map_right_inverse Prod.map_rightInverse
 
+/- warning: prod.map_involutive -> Prod.map_involutive is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : Nonempty.{succ u1} α] [_inst_2 : Nonempty.{succ u2} β] {f : α -> α} {g : β -> β}, Iff (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.map.{u1, u1, u2, u2} α α β β f g)) (And (Function.Involutive.{succ u1} α f) (Function.Involutive.{succ u2} β g))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : Nonempty.{succ u2} α] [_inst_2 : Nonempty.{succ u1} β] {f : α -> α} {g : β -> β}, Iff (Function.Involutive.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) (Prod.map.{u2, u2, u1, u1} α α β β f g)) (And (Function.Involutive.{succ u2} α f) (Function.Involutive.{succ u1} β g))
+Case conversion may be inaccurate. Consider using '#align prod.map_involutive Prod.map_involutiveₓ'. -/
 @[simp]
 theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → β} :
     Involutive (map f g) ↔ Involutive f ∧ Involutive g :=

Changes in mathlib4

mathlib3
mathlib4
chore: remove autoImplicit from more files (#11798)

and reduce its scope in a few other instances. Mostly in CategoryTheory and Data this time; some Combinatorics also.

Co-authored-by: Richard Osborn <richardosborn@mac.com>

Diff
@@ -16,8 +16,6 @@ This file defines `Prod.swap : α × β → β × α` and proves various simple
 It also defines better delaborators for product projections.
 -/
 
-set_option autoImplicit true
-
 variable {α : Type*} {β : Type*} {γ : Type*} {δ : Type*}
 
 @[simp]
@@ -114,10 +112,10 @@ theorem mk.inj_right {α β : Type*} (b : β) :
   simpa only [and_true, eq_self_iff_true, mk.inj_iff] using h
 #align prod.mk.inj_right Prod.mk.inj_right
 
-lemma mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ := (mk.inj_left _).eq_iff
+lemma mk_inj_left {a : α} {b₁ b₂ : β} : (a, b₁) = (a, b₂) ↔ b₁ = b₂ := (mk.inj_left _).eq_iff
 #align prod.mk_inj_left Prod.mk_inj_left
 
-lemma mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).eq_iff
+lemma mk_inj_right {a₁ a₂ : α} {b : β} : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).eq_iff
 #align prod.mk_inj_right Prod.mk_inj_right
 
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
chore: superfluous parentheses (#12116)

Co-authored-by: Moritz Firsching <firsching@google.com>

Diff
@@ -376,7 +376,7 @@ theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ
     Bijective (map f g) ↔ Bijective f ∧ Bijective g := by
   haveI := Nonempty.map f ‹_›
   haveI := Nonempty.map g ‹_›
-  exact (map_injective.and map_surjective).trans (and_and_and_comm)
+  exact (map_injective.and map_surjective).trans and_and_and_comm
 #align prod.map_bijective Prod.map_bijective
 
 @[simp]
chore: update unexpanders (#11165)

lean4#3375 makes it so that unexpanders do not need to handle overapplication.

Diff
@@ -404,32 +404,21 @@ theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → 
   map_leftInverse
 #align prod.map_involutive Prod.map_involutive
 
-end Prod
-
 section delaborators
 open Lean PrettyPrinter Delaborator
 
-/-- Delaborator for simple product projections. -/
-@[delab app.Prod.fst, delab app.Prod.snd]
-def delabProdProjs : Delab := do
-  let #[_, _, _] := (← SubExpr.getExpr).getAppArgs | failure
-  let stx ← delabProjectionApp
-  match stx with
-  | `($(x).fst) => `($(x).1)
-  | `($(x).snd) => `($(x).2)
-  | _ => failure
-
-/-- Delaborator for product first projection when the projection is a function
-that is then applied. -/
-@[app_unexpander Prod.fst]
-def unexpandProdFst : Lean.PrettyPrinter.Unexpander
-  | `($(_) $p $xs*) => `($p.1 $xs*)
-  | _ => throw ()
-
-/-- Delaborator for product second projection when the projection is a function
-that is then applied. -/
-@[app_unexpander Prod.snd]
-def unexpandProdSnd : Lean.PrettyPrinter.Unexpander
-  | `($(_) $p $xs*) => `($p.2 $xs*)
-  | _ => throw ()
+/-- Delaborator for `Prod.fst x` as `x.1`. -/
+@[delab app.Prod.fst]
+def delabProdFst : Delab := withOverApp 3 do
+  let x ← SubExpr.withAppArg delab
+  `($(x).1)
+
+/-- Delaborator for `Prod.snd x` as `x.2`. -/
+@[delab app.Prod.snd]
+def delabProdSnd : Delab := withOverApp 3 do
+  let x ← SubExpr.withAppArg delab
+  `($(x).2)
+
 end delaborators
+
+end Prod
chore: reduce imports (#9830)

This uses the improved shake script from #9772 to reduce imports across mathlib. The corresponding noshake.json file has been added to #9772.

Co-authored-by: Mario Carneiro <di.gama@gmail.com>

Diff
@@ -3,7 +3,6 @@ Copyright (c) 2017 Johannes Hölzl. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 -/
-import Mathlib.Init.Core
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
 import Mathlib.Tactic.Inhabit
chore: bump Std dependency up to leanprover/std4#511 (#9609)

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -226,12 +226,6 @@ theorem snd_eq_iff : ∀ {p : α × β} {x : β}, p.2 = x ↔ p = (p.1, x)
 
 variable {r : α → α → Prop} {s : β → β → Prop} {x y : α × β}
 
-theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × β} :
-    Prod.Lex r s p q ↔ r p.1 q.1 ∨ p.1 = q.1 ∧ s p.2 q.2 :=
-  ⟨fun h ↦ by cases h <;> simp [*], fun h ↦
-    match p, q, h with
-    | (a, b), (c, d), Or.inl h => Lex.left _ _ h
-    | (a, b), (c, d), Or.inr ⟨e, h⟩ => by subst e; exact Lex.right _ h⟩
 #align prod.lex_def Prod.lex_def
 
 lemma lex_iff : Prod.Lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 := lex_def _ _
chore(*): replace $ with <| (#9319)

See Zulip thread for the discussion.

Diff
@@ -303,7 +303,7 @@ instance IsTrichotomous [IsTrichotomous α r] [IsTrichotomous β s] :
   obtain hij | rfl | hji := trichotomous_of r i j
   { exact Or.inl (Lex.left _ _ hij) }
   { exact (trichotomous_of (s) a b).imp3 (Lex.right _) (congr_arg _) (Lex.right _) }
-  { exact Or.inr (Or.inr $ Lex.left _ _ hji) }⟩
+  { exact Or.inr (Or.inr <| Lex.left _ _ hji) }⟩
 
 end Prod
 
chore: bump std4 (#8548)
Diff
@@ -125,9 +125,6 @@ theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
   rw [mk.inj_iff]
 #align prod.ext_iff Prod.ext_iff
 
-@[ext]
-theorem ext {α β} {p q : α × β} (h₁ : p.1 = q.1) (h₂ : p.2 = q.2) : p = q :=
-  ext_iff.2 ⟨h₁, h₂⟩
 #align prod.ext Prod.ext
 
 theorem map_def {f : α → γ} {g : β → δ} : Prod.map f g = fun p : α × β ↦ (f p.1, g p.2) :=
feat: long overdue delaborators (#7633)

This brings to Mathlib assorted delaborators written by @kmill for various projects including Mathematics in Lean. They mostly fix regressions compared to Lean 3.

Co-authored-by: Mario Carneiro <mcarneir@andrew.cmu.edu>

Diff
@@ -14,6 +14,7 @@ import Mathlib.Tactic.Inhabit
 # Extra facts about `Prod`
 
 This file defines `Prod.swap : α × β → β × α` and proves various simple lemmas about `Prod`.
+It also defines better delaborators for product projections.
 -/
 
 set_option autoImplicit true
@@ -414,3 +415,31 @@ theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → 
 #align prod.map_involutive Prod.map_involutive
 
 end Prod
+
+section delaborators
+open Lean PrettyPrinter Delaborator
+
+/-- Delaborator for simple product projections. -/
+@[delab app.Prod.fst, delab app.Prod.snd]
+def delabProdProjs : Delab := do
+  let #[_, _, _] := (← SubExpr.getExpr).getAppArgs | failure
+  let stx ← delabProjectionApp
+  match stx with
+  | `($(x).fst) => `($(x).1)
+  | `($(x).snd) => `($(x).2)
+  | _ => failure
+
+/-- Delaborator for product first projection when the projection is a function
+that is then applied. -/
+@[app_unexpander Prod.fst]
+def unexpandProdFst : Lean.PrettyPrinter.Unexpander
+  | `($(_) $p $xs*) => `($p.1 $xs*)
+  | _ => throw ()
+
+/-- Delaborator for product second projection when the projection is a function
+that is then applied. -/
+@[app_unexpander Prod.snd]
+def unexpandProdSnd : Lean.PrettyPrinter.Unexpander
+  | `($(_) $p $xs*) => `($p.2 $xs*)
+  | _ => throw ()
+end delaborators
chore: delay import of Tactic.Common (#7000)

I know that this is contrary to what we've done previously, but:

  • I'm trying to upstream a great many tactics from Mathlib to Std (essentially, everything that non-mathematicians want too).
  • This makes it much easier for me to see what is going on, and understand the import requirements (particularly for the "big" tactics norm_num / ring / linarith)
  • It's actually not as bad as it looks here, because as these tactics move up to Std they will start disappearing again from explicit imports, but Mathlib can happily import all of Std.

(Oh

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -6,7 +6,7 @@ Authors: Johannes Hölzl
 import Mathlib.Init.Core
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
-import Mathlib.Tactic.Common
+import Mathlib.Tactic.Inhabit
 
 #align_import data.prod.basic from "leanprover-community/mathlib"@"d07245fd37786daa997af4f1a73a49fa3b748408"
 
chore: cleanup Mathlib.Init.Data.Prod (#6972)

Removing from Mathlib.Init.Data.Prod from the early parts of the import hierarchy.

While at it, remove unnecessary uses of Prod.mk.eta across the library.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -4,7 +4,6 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 -/
 import Mathlib.Init.Core
-import Mathlib.Init.Data.Prod
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
 import Mathlib.Tactic.Common
@@ -28,6 +27,10 @@ theorem Prod_map (f : α → γ) (g : β → δ) (p : α × β) : Prod.map f g p
 
 namespace Prod
 
+@[simp]
+theorem mk.eta : ∀ {p : α × β}, (p.1, p.2) = p
+  | (_, _) => rfl
+
 @[simp]
 theorem «forall» {p : α × β → Prop} : (∀ x, p x) ↔ ∀ a b, p (a, b) :=
   ⟨fun h a b ↦ h (a, b), fun h ⟨a, b⟩ ↦ h a b⟩
@@ -118,7 +121,7 @@ lemma mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).e
 #align prod.mk_inj_right Prod.mk_inj_right
 
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
-  rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
+  rw [mk.inj_iff]
 #align prod.ext_iff Prod.ext_iff
 
 @[ext]
fix: disable autoImplicit globally (#6528)

Autoimplicits are highly controversial and also defeat the performance-improving work in #6474.

The intent of this PR is to make autoImplicit opt-in on a per-file basis, by disabling it in the lakefile and enabling it again with set_option autoImplicit true in the few files that rely on it.

That also keeps this PR small, as opposed to attempting to "fix" files to not need it any more.

I claim that many of the uses of autoImplicit in these files are accidental; situations such as:

  • Assuming variables are in scope, but pasting the lemma in the wrong section
  • Pasting in a lemma from a scratch file without checking to see if the variable names are consistent with the rest of the file
  • Making a copy-paste error between lemmas and forgetting to add an explicit arguments.

Having set_option autoImplicit false as the default prevents these types of mistake being made in the 90% of files where autoImplicits are not used at all, and causes them to be caught by CI during review.

I think there were various points during the port where we encouraged porters to delete the universes u v lines; I think having autoparams for universe variables only would cover a lot of the cases we actually use them, while avoiding any real shortcomings.

A Zulip poll (after combining overlapping votes accordingly) was in favor of this change with 5:5:18 as the no:dontcare:yes vote ratio.

While this PR was being reviewed, a handful of files gained some more likely-accidental autoImplicits. In these places, set_option autoImplicit true has been placed locally within a section, rather than at the top of the file.

Diff
@@ -17,6 +17,8 @@ import Mathlib.Tactic.Common
 This file defines `Prod.swap : α × β → β × α` and proves various simple lemmas about `Prod`.
 -/
 
+set_option autoImplicit true
+
 variable {α : Type*} {β : Type*} {γ : Type*} {δ : Type*}
 
 @[simp]
chore: banish Type _ and Sort _ (#6499)

We remove all possible occurences of Type _ and Sort _ in favor of Type* and Sort*.

This has nice performance benefits.

Diff
@@ -17,7 +17,7 @@ import Mathlib.Tactic.Common
 This file defines `Prod.swap : α × β → β × α` and proves various simple lemmas about `Prod`.
 -/
 
-variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
+variable {α : Type*} {β : Type*} {γ : Type*} {δ : Type*}
 
 @[simp]
 theorem Prod_map (f : α → γ) (g : β → δ) (p : α × β) : Prod.map f g p = (f p.1, g p.2) :=
@@ -78,7 +78,7 @@ theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘
 /-- Composing a `Prod.map` with another `Prod.map` is equal to
 a single `Prod.map` of composed functions.
 -/
-theorem map_comp_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) :
+theorem map_comp_map {ε ζ : Type*} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) :
     Prod.map g g' ∘ Prod.map f f' = Prod.map (g ∘ f) (g' ∘ f') :=
   rfl
 #align prod.map_comp_map Prod.map_comp_map
@@ -86,7 +86,7 @@ theorem map_comp_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β 
 /-- Composing a `Prod.map` with another `Prod.map` is equal to
 a single `Prod.map` of composed functions, fully applied.
 -/
-theorem map_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) (x : α × γ) :
+theorem map_map {ε ζ : Type*} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) (x : α × γ) :
     Prod.map g g' (Prod.map f f' x) = Prod.map (g ∘ f) (g' ∘ f') x :=
   rfl
 #align prod.map_map Prod.map_map
@@ -98,12 +98,12 @@ theorem mk.inj_iff {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) = (a₂, b
   Iff.of_eq (mk.injEq _ _ _ _)
 #align prod.mk.inj_iff Prod.mk.inj_iff
 
-theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
+theorem mk.inj_left {α β : Type*} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
   intro b₁ b₂ h
   simpa only [true_and, Prod.mk.inj_iff, eq_self_iff_true] using h
 #align prod.mk.inj_left Prod.mk.inj_left
 
-theorem mk.inj_right {α β : Type _} (b : β) :
+theorem mk.inj_right {α β : Type*} (b : β) :
     Function.Injective (fun a ↦ Prod.mk a b : α → α × β) := by
   intro b₁ b₂ h
   simpa only [and_true, eq_self_iff_true, mk.inj_iff] using h
chore: script to replace headers with #align_import statements (#5979)

Open in Gitpod

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -2,11 +2,6 @@
 Copyright (c) 2017 Johannes Hölzl. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
-
-! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit d07245fd37786daa997af4f1a73a49fa3b748408
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod
@@ -14,6 +9,8 @@ import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
 import Mathlib.Tactic.Common
 
+#align_import data.prod.basic from "leanprover-community/mathlib"@"d07245fd37786daa997af4f1a73a49fa3b748408"
+
 /-!
 # Extra facts about `Prod`
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit 48fb5b5280e7c81672afc9524185ae994553ebf4
+! leanprover-community/mathlib commit d07245fd37786daa997af4f1a73a49fa3b748408
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -135,6 +135,7 @@ theorem id_prod : (fun p : α × β ↦ (p.1, p.2)) = id :=
   rfl
 #align prod.id_prod Prod.id_prod
 
+@[simp]
 theorem map_id : Prod.map (@id α) (@id β) = id :=
   id_prod
 #align prod.map_id Prod.map_id
refactor: move all register_simp_attrs to 1 file (#5681)

There are slight differences between mathlib3 and mathlib4 (different set of attributes, different lemmas are in core/std), so I redid the same refactor instead of forward-porting changes.

mathlib3 PR: leanprover-community/mathlib#19223

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit bd9851ca476957ea4549eb19b40e7b5ade9428cc
+! leanprover-community/mathlib commit 48fb5b5280e7c81672afc9524185ae994553ebf4
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -57,7 +57,7 @@ theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Func
   rfl
 #align prod.fst_comp_mk Prod.fst_comp_mk
 
-@[simp]
+@[simp, mfld_simps]
 theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) :=
   rfl
 #align prod.map_mk Prod.map_mk
chore: tidy various files (#5268)
Diff
@@ -113,9 +113,10 @@ theorem mk.inj_right {α β : Type _} (b : β) :
 #align prod.mk.inj_right Prod.mk.inj_right
 
 lemma mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ := (mk.inj_left _).eq_iff
+#align prod.mk_inj_left Prod.mk_inj_left
+
 lemma mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).eq_iff
 #align prod.mk_inj_right Prod.mk_inj_right
-#align prod.mk_inj_left Prod.mk_inj_left
 
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
   rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
chore: formatting issues (#4947)

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Diff
@@ -257,7 +257,7 @@ instance {r : α → α → Prop} {s : β → β → Prop} [IsRefl β s] : IsRef
   ⟨Lex.refl_right _ _⟩
 
 instance isIrrefl [IsIrrefl α r] [IsIrrefl β s] : IsIrrefl (α × β) (Prod.Lex r s) :=
-⟨by rintro ⟨i, a⟩ (⟨_, _, h⟩ | ⟨_, h⟩) <;> exact irrefl _ h⟩
+  ⟨by rintro ⟨i, a⟩ (⟨_, _, h⟩ | ⟨_, h⟩) <;> exact irrefl _ h⟩
 
 @[trans]
 theorem Lex.trans {r : α → α → Prop} {s : β → β → Prop} [IsTrans α r] [IsTrans β s] :
chore: fix upper/lowercase in comments (#4360)
  • Run a non-interactive version of fix-comments.py on all files.
  • Go through the diff and manually add/discard/edit chunks.
Diff
@@ -15,9 +15,9 @@ import Mathlib.Logic.Function.Basic
 import Mathlib.Tactic.Common
 
 /-!
-# Extra facts about `prod`
+# Extra facts about `Prod`
 
-This file defines `prod.swap : α × β → β × α` and proves various simple lemmas about `prod`.
+This file defines `Prod.swap : α × β → β × α` and proves various simple lemmas about `Prod`.
 -/
 
 variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
feat: add Mathlib.Tactic.Common, and import (#4056)

This makes a mathlib4 version of mathlib3's tactic.basic, now called Mathlib.Tactic.Common, which imports all tactics which do not have significant theory requirements, and then is imported all across the base of the hierarchy.

This ensures that all common tactics are available nearly everywhere in the library, rather than having to be imported one-by-one as you need them.

Co-authored-by: Scott Morrison <scott.morrison@gmail.com>

Diff
@@ -12,7 +12,7 @@ import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
-import Mathlib.Tactic.Inhabit
+import Mathlib.Tactic.Common
 
 /-!
 # Extra facts about `prod`
Revert "feat: add Mathlib.Tactic.Common, and import"

This reverts commit 1ce2f69b.

Diff
@@ -12,7 +12,7 @@ import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
-import Mathlib.Tactic.Common
+import Mathlib.Tactic.Inhabit
 
 /-!
 # Extra facts about `prod`
feat: add Mathlib.Tactic.Common, and import
Diff
@@ -12,7 +12,7 @@ import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
-import Mathlib.Tactic.Inhabit
+import Mathlib.Tactic.Common
 
 /-!
 # Extra facts about `prod`
feat: forward-port leanprover-community/mathlib#18446 (#2346)

Co-authored-by: Jon Eugster <eugster.jon@gmail.com>

Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit 2ed7e4aec72395b6a7c3ac4ac7873a7a43ead17c
+! leanprover-community/mathlib commit bd9851ca476957ea4549eb19b40e7b5ade9428cc
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -12,6 +12,7 @@ import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod
 import Mathlib.Init.Function
 import Mathlib.Logic.Function.Basic
+import Mathlib.Tactic.Inhabit
 
 /-!
 # Extra facts about `prod`
@@ -341,3 +342,71 @@ theorem Involutive.Prod_map {f : α → α} {g : β → β} :
 #align function.involutive.prod_map Function.Involutive.Prod_map
 
 end Function
+
+namespace Prod
+
+open Function
+
+@[simp]
+theorem map_injective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
+    Injective (map f g) ↔ Injective f ∧ Injective g :=
+  ⟨fun h =>
+    ⟨fun a₁ a₂ ha => by
+      inhabit β
+      injection
+        @h (a₁, default) (a₂, default) (congr_arg (fun c : γ => Prod.mk c (g default)) ha : _),
+      fun b₁ b₂ hb => by
+      inhabit α
+      injection @h (default, b₁) (default, b₂) (congr_arg (Prod.mk (f default)) hb : _)⟩,
+    fun h => h.1.Prod_map h.2⟩
+#align prod.map_injective Prod.map_injective
+
+@[simp]
+theorem map_surjective [Nonempty γ] [Nonempty δ] {f : α → γ} {g : β → δ} :
+    Surjective (map f g) ↔ Surjective f ∧ Surjective g :=
+  ⟨fun h =>
+    ⟨fun c => by
+      inhabit δ
+      obtain ⟨⟨a, b⟩, h⟩ := h (c, default)
+      exact ⟨a, congr_arg Prod.fst h⟩,
+      fun d => by
+      inhabit γ
+      obtain ⟨⟨a, b⟩, h⟩ := h (default, d)
+      exact ⟨b, congr_arg Prod.snd h⟩⟩,
+    fun h => h.1.Prod_map h.2⟩
+#align prod.map_surjective Prod.map_surjective
+
+@[simp]
+theorem map_bijective [Nonempty α] [Nonempty β] {f : α → γ} {g : β → δ} :
+    Bijective (map f g) ↔ Bijective f ∧ Bijective g := by
+  haveI := Nonempty.map f ‹_›
+  haveI := Nonempty.map g ‹_›
+  exact (map_injective.and map_surjective).trans (and_and_and_comm)
+#align prod.map_bijective Prod.map_bijective
+
+@[simp]
+theorem map_leftInverse [Nonempty β] [Nonempty δ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
+    {g₂ : δ → γ} : LeftInverse (map f₁ g₁) (map f₂ g₂) ↔ LeftInverse f₁ f₂ ∧ LeftInverse g₁ g₂ :=
+  ⟨fun h =>
+    ⟨fun b => by
+      inhabit δ
+      exact congr_arg Prod.fst (h (b, default)),
+      fun d => by
+      inhabit β
+      exact congr_arg Prod.snd (h (default, d))⟩,
+    fun h => h.1.Prod_map h.2 ⟩
+#align prod.map_left_inverse Prod.map_leftInverse
+
+@[simp]
+theorem map_rightInverse [Nonempty α] [Nonempty γ] {f₁ : α → β} {g₁ : γ → δ} {f₂ : β → α}
+    {g₂ : δ → γ} : RightInverse (map f₁ g₁) (map f₂ g₂) ↔ RightInverse f₁ f₂ ∧ RightInverse g₁ g₂ :=
+  map_leftInverse
+#align prod.map_right_inverse Prod.map_rightInverse
+
+@[simp]
+theorem map_involutive [Nonempty α] [Nonempty β] {f : α → α} {g : β → β} :
+    Involutive (map f g) ↔ Involutive f ∧ Involutive g :=
+  map_leftInverse
+#align prod.map_involutive Prod.map_involutive
+
+end Prod
chore: add missing #align statements (#1902)

This PR is the result of a slight variant on the following "algorithm"

  • take all mathlib 3 names, remove _ and make all uppercase letters into lowercase
  • take all mathlib 4 names, remove _ and make all uppercase letters into lowercase
  • look for matches, and create pairs (original_lean3_name, OriginalLean4Name)
  • for pairs that do not have an align statement:
    • use Lean 4 to lookup the file + position of the Lean 4 name
    • add an #align statement just before the next empty line
  • manually fix some tiny mistakes (e.g., empty lines in proofs might cause the #align statement to have been inserted too early)
Diff
@@ -31,40 +31,51 @@ namespace Prod
 @[simp]
 theorem «forall» {p : α × β → Prop} : (∀ x, p x) ↔ ∀ a b, p (a, b) :=
   ⟨fun h a b ↦ h (a, b), fun h ⟨a, b⟩ ↦ h a b⟩
+#align prod.forall Prod.forall
 
 @[simp]
 theorem «exists» {p : α × β → Prop} : (∃ x, p x) ↔ ∃ a b, p (a, b) :=
   ⟨fun ⟨⟨a, b⟩, h⟩ ↦ ⟨a, b, h⟩, fun ⟨a, b, h⟩ ↦ ⟨⟨a, b⟩, h⟩⟩
+#align prod.exists Prod.exists
 
 theorem forall' {p : α → β → Prop} : (∀ x : α × β, p x.1 x.2) ↔ ∀ a b, p a b :=
   Prod.forall
+#align prod.forall' Prod.forall'
 
 theorem exists' {p : α → β → Prop} : (∃ x : α × β, p x.1 x.2) ↔ ∃ a b, p a b :=
   Prod.exists
+#align prod.exists' Prod.exists'
 
 @[simp]
 theorem snd_comp_mk (x : α) : Prod.snd ∘ (Prod.mk x : β → α × β) = id :=
   rfl
+#align prod.snd_comp_mk Prod.snd_comp_mk
 
 @[simp]
 theorem fst_comp_mk (x : α) : Prod.fst ∘ (Prod.mk x : β → α × β) = Function.const β x :=
   rfl
+#align prod.fst_comp_mk Prod.fst_comp_mk
 
 @[simp]
 theorem map_mk (f : α → γ) (g : β → δ) (a : α) (b : β) : map f g (a, b) = (f a, g b) :=
   rfl
+#align prod.map_mk Prod.map_mk
 
 theorem map_fst (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).1 = f p.1 :=
   rfl
+#align prod.map_fst Prod.map_fst
 
 theorem map_snd (f : α → γ) (g : β → δ) (p : α × β) : (map f g p).2 = g p.2 :=
   rfl
+#align prod.map_snd Prod.map_snd
 
 theorem map_fst' (f : α → γ) (g : β → δ) : Prod.fst ∘ map f g = f ∘ Prod.fst :=
   funext <| map_fst f g
+#align prod.map_fst' Prod.map_fst'
 
 theorem map_snd' (f : α → γ) (g : β → δ) : Prod.snd ∘ map f g = g ∘ Prod.snd :=
   funext <| map_snd f g
+#align prod.map_snd' Prod.map_snd'
 
 /-- Composing a `Prod.map` with another `Prod.map` is equal to
 a single `Prod.map` of composed functions.
@@ -72,6 +83,7 @@ a single `Prod.map` of composed functions.
 theorem map_comp_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) :
     Prod.map g g' ∘ Prod.map f f' = Prod.map (g ∘ f) (g' ∘ f') :=
   rfl
+#align prod.map_comp_map Prod.map_comp_map
 
 /-- Composing a `Prod.map` with another `Prod.map` is equal to
 a single `Prod.map` of composed functions, fully applied.
@@ -79,27 +91,34 @@ a single `Prod.map` of composed functions, fully applied.
 theorem map_map {ε ζ : Type _} (f : α → β) (f' : γ → δ) (g : β → ε) (g' : δ → ζ) (x : α × γ) :
     Prod.map g g' (Prod.map f f' x) = Prod.map (g ∘ f) (g' ∘ f') x :=
   rfl
+#align prod.map_map Prod.map_map
 
 -- Porting note: mathlib3 proof uses `by cc` for the mpr direction
 -- Porting note: `@[simp]` tag removed because auto-generated `mk.injEq` simplifies LHS
 -- @[simp]
 theorem mk.inj_iff {a₁ a₂ : α} {b₁ b₂ : β} : (a₁, b₁) = (a₂, b₂) ↔ a₁ = a₂ ∧ b₁ = b₂ :=
   Iff.of_eq (mk.injEq _ _ _ _)
+#align prod.mk.inj_iff Prod.mk.inj_iff
 
 theorem mk.inj_left {α β : Type _} (a : α) : Function.Injective (Prod.mk a : β → α × β) := by
   intro b₁ b₂ h
   simpa only [true_and, Prod.mk.inj_iff, eq_self_iff_true] using h
+#align prod.mk.inj_left Prod.mk.inj_left
 
 theorem mk.inj_right {α β : Type _} (b : β) :
     Function.Injective (fun a ↦ Prod.mk a b : α → α × β) := by
   intro b₁ b₂ h
   simpa only [and_true, eq_self_iff_true, mk.inj_iff] using h
+#align prod.mk.inj_right Prod.mk.inj_right
 
 lemma mk_inj_left : (a, b₁) = (a, b₂) ↔ b₁ = b₂ := (mk.inj_left _).eq_iff
 lemma mk_inj_right : (a₁, b) = (a₂, b) ↔ a₁ = a₂ := (mk.inj_right _).eq_iff
+#align prod.mk_inj_right Prod.mk_inj_right
+#align prod.mk_inj_left Prod.mk_inj_left
 
 theorem ext_iff {p q : α × β} : p = q ↔ p.1 = q.1 ∧ p.2 = q.2 := by
   rw [← @mk.eta _ _ p, ← @mk.eta _ _ q, mk.inj_iff]
+#align prod.ext_iff Prod.ext_iff
 
 @[ext]
 theorem ext {α β} {p q : α × β} (h₁ : p.1 = q.1) (h₂ : p.2 = q.2) : p = q :=
@@ -108,47 +127,60 @@ theorem ext {α β} {p q : α × β} (h₁ : p.1 = q.1) (h₂ : p.2 = q.2) : p =
 
 theorem map_def {f : α → γ} {g : β → δ} : Prod.map f g = fun p : α × β ↦ (f p.1, g p.2) :=
   funext fun p ↦ ext (map_fst f g p) (map_snd f g p)
+#align prod.map_def Prod.map_def
 
 theorem id_prod : (fun p : α × β ↦ (p.1, p.2)) = id :=
   rfl
+#align prod.id_prod Prod.id_prod
 
 theorem map_id : Prod.map (@id α) (@id β) = id :=
   id_prod
+#align prod.map_id Prod.map_id
 
 theorem fst_surjective [h : Nonempty β] : Function.Surjective (@fst α β) :=
   fun x ↦ h.elim fun y ↦ ⟨⟨x, y⟩, rfl⟩
+#align prod.fst_surjective Prod.fst_surjective
 
 theorem snd_surjective [h : Nonempty α] : Function.Surjective (@snd α β) :=
   fun y ↦ h.elim fun x ↦ ⟨⟨x, y⟩, rfl⟩
+#align prod.snd_surjective Prod.snd_surjective
 
 theorem fst_injective [Subsingleton β] : Function.Injective (@fst α β) :=
   fun _ _ h ↦ ext h (Subsingleton.elim _ _)
+#align prod.fst_injective Prod.fst_injective
 
 theorem snd_injective [Subsingleton α] : Function.Injective (@snd α β) :=
   fun _ _ h ↦ ext (Subsingleton.elim _ _) h
+#align prod.snd_injective Prod.snd_injective
 
 /-- Swap the factors of a product. `swap (a, b) = (b, a)` -/
 def swap : α × β → β × α := fun p ↦ (p.2, p.1)
+#align prod.swap Prod.swap
 
 @[simp]
 theorem swap_swap : ∀ x : α × β, swap (swap x) = x
   | ⟨_, _⟩ => rfl
+#align prod.swap_swap Prod.swap_swap
 
 @[simp]
 theorem fst_swap {p : α × β} : (swap p).1 = p.2 :=
   rfl
+#align prod.fst_swap Prod.fst_swap
 
 @[simp]
 theorem snd_swap {p : α × β} : (swap p).2 = p.1 :=
   rfl
+#align prod.snd_swap Prod.snd_swap
 
 @[simp]
 theorem swap_prod_mk {a : α} {b : β} : swap (a, b) = (b, a) :=
   rfl
+#align prod.swap_prod_mk Prod.swap_prod_mk
 
 @[simp]
 theorem swap_swap_eq : swap ∘ swap = @id (α × β) :=
   funext swap_swap
+#align prod.swap_swap_eq Prod.swap_swap_eq
 
 @[simp]
 theorem swap_leftInverse : Function.LeftInverse (@swap α β) swap :=
@@ -162,25 +194,32 @@ theorem swap_rightInverse : Function.RightInverse (@swap α β) swap :=
 
 theorem swap_injective : Function.Injective (@swap α β) :=
   swap_leftInverse.injective
+#align prod.swap_injective Prod.swap_injective
 
 theorem swap_surjective : Function.Surjective (@swap α β) :=
   swap_leftInverse.surjective
+#align prod.swap_surjective Prod.swap_surjective
 
 theorem swap_bijective : Function.Bijective (@swap α β) :=
   ⟨swap_injective, swap_surjective⟩
+#align prod.swap_bijective Prod.swap_bijective
 
 @[simp]
 theorem swap_inj {p q : α × β} : swap p = swap q ↔ p = q :=
   swap_injective.eq_iff
+#align prod.swap_inj Prod.swap_inj
 
 theorem eq_iff_fst_eq_snd_eq : ∀ {p q : α × β}, p = q ↔ p.1 = q.1 ∧ p.2 = q.2
   | ⟨p₁, p₂⟩, ⟨q₁, q₂⟩ => by simp
+#align prod.eq_iff_fst_eq_snd_eq Prod.eq_iff_fst_eq_snd_eq
 
 theorem fst_eq_iff : ∀ {p : α × β} {x : α}, p.1 = x ↔ p = (x, p.2)
   | ⟨a, b⟩, x => by simp
+#align prod.fst_eq_iff Prod.fst_eq_iff
 
 theorem snd_eq_iff : ∀ {p : α × β} {x : β}, p.2 = x ↔ p = (p.1, x)
   | ⟨a, b⟩, x => by simp
+#align prod.snd_eq_iff Prod.snd_eq_iff
 
 variable {r : α → α → Prop} {s : β → β → Prop} {x y : α × β}
 
@@ -190,8 +229,10 @@ theorem lex_def (r : α → α → Prop) (s : β → β → Prop) {p q : α × 
     match p, q, h with
     | (a, b), (c, d), Or.inl h => Lex.left _ _ h
     | (a, b), (c, d), Or.inr ⟨e, h⟩ => by subst e; exact Lex.right _ h⟩
+#align prod.lex_def Prod.lex_def
 
 lemma lex_iff : Prod.Lex r s x y ↔ r x.1 y.1 ∨ x.1 = y.1 ∧ s x.2 y.2 := lex_def _ _
+#align prod.lex_iff Prod.lex_iff
 
 instance Lex.decidable [DecidableEq α]
     (r : α → α → Prop) (s : β → β → Prop) [DecidableRel r] [DecidableRel s] :
@@ -201,6 +242,7 @@ instance Lex.decidable [DecidableEq α]
 @[refl]
 theorem Lex.refl_left (r : α → α → Prop) (s : β → β → Prop) [IsRefl α r] : ∀ x, Prod.Lex r s x x
   | (_, _) => Lex.left _ _ (refl _)
+#align prod.lex.refl_left Prod.Lex.refl_left
 
 instance {r : α → α → Prop} {s : β → β → Prop} [IsRefl α r] : IsRefl (α × β) (Prod.Lex r s) :=
   ⟨Lex.refl_left _ _⟩
@@ -208,6 +250,7 @@ instance {r : α → α → Prop} {s : β → β → Prop} [IsRefl α r] : IsRef
 @[refl]
 theorem Lex.refl_right (r : α → α → Prop) (s : β → β → Prop) [IsRefl β s] : ∀ x, Prod.Lex r s x x
   | (_, _) => Lex.right _ (refl _)
+#align prod.lex.refl_right Prod.Lex.refl_right
 
 instance {r : α → α → Prop} {s : β → β → Prop} [IsRefl β s] : IsRefl (α × β) (Prod.Lex r s) :=
   ⟨Lex.refl_right _ _⟩
@@ -222,6 +265,7 @@ theorem Lex.trans {r : α → α → Prop} {s : β → β → Prop} [IsTrans α
   | (_, _), (_, _), (_, _), left  _ _ hxy₁, right _ _      => left  _ _ hxy₁
   | (_, _), (_, _), (_, _), right _ _,      left  _ _ hyz₁ => left  _ _ hyz₁
   | (_, _), (_, _), (_, _), right _ hxy₂,   right _ hyz₂   => right _ (_root_.trans hxy₂ hyz₂)
+#align prod.lex.trans Prod.Lex.trans
 
 instance {r : α → α → Prop} {s : β → β → Prop} [IsTrans α r] [IsTrans β s] :
   IsTrans (α × β) (Prod.Lex r s) :=
Feat: prove IsTrans α r → Trans r r r and Trans r r r → IsTrans α r (#1522)

Now Trans.trans conflicts with _root_.trans.

Diff
@@ -231,7 +231,7 @@ instance {r : α → α → Prop} {s : β → β → Prop} [IsStrictOrder α r]
     IsAntisymm (α × β) (Prod.Lex r s) :=
   ⟨fun x₁ x₂ h₁₂ h₂₁ ↦
     match x₁, x₂, h₁₂, h₂₁ with
-    | (a, _), (_, _), .left  _ _ hr₁, .left  _ _ hr₂ => (irrefl a (trans hr₁ hr₂)).elim
+    | (a, _), (_, _), .left  _ _ hr₁, .left  _ _ hr₂ => (irrefl a (_root_.trans hr₁ hr₂)).elim
     | (_, _), (_, _), .left  _ _ hr₁, .right _ _     => (irrefl _ hr₁).elim
     | (_, _), (_, _), .right _ _,     .left  _ _ hr₂ => (irrefl _ hr₂).elim
     | (_, _), (_, _), .right _ hs₁,   .right _ hs₂   => antisymm hs₁ hs₂ ▸ rfl⟩
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
 
 ! This file was ported from Lean 3 source module data.prod.basic
-! leanprover-community/mathlib commit eb620d2d94ab3c45bcae98b681984b4c309f2e28
+! leanprover-community/mathlib commit 2ed7e4aec72395b6a7c3ac4ac7873a7a43ead17c
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
chore: fix more casing errors per naming scheme (#1232)

I've avoided anything under Tactic or test.

In correcting the names, I found Option.isNone_iff_eq_none duplicated between Std and Mathlib, so the Mathlib one has been removed.

Co-authored-by: Reid Barton <rwbarton@gmail.com>

Diff
@@ -212,7 +212,7 @@ theorem Lex.refl_right (r : α → α → Prop) (s : β → β → Prop) [IsRefl
 instance {r : α → α → Prop} {s : β → β → Prop} [IsRefl β s] : IsRefl (α × β) (Prod.Lex r s) :=
   ⟨Lex.refl_right _ _⟩
 
-instance is_irrefl [IsIrrefl α r] [IsIrrefl β s] : IsIrrefl (α × β) (Prod.Lex r s) :=
+instance isIrrefl [IsIrrefl α r] [IsIrrefl β s] : IsIrrefl (α × β) (Prod.Lex r s) :=
 ⟨by rintro ⟨i, a⟩ (⟨_, _, h⟩ | ⟨_, h⟩) <;> exact irrefl _ h⟩
 
 @[trans]
chore: add source headers to ported theory files (#1094)

The script used to do this is included. The yaml file was obtained from https://raw.githubusercontent.com/wiki/leanprover-community/mathlib/mathlib4-port-status.md

Diff
@@ -2,6 +2,11 @@
 Copyright (c) 2017 Johannes Hölzl. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl
+
+! This file was ported from Lean 3 source module data.prod.basic
+! leanprover-community/mathlib commit eb620d2d94ab3c45bcae98b681984b4c309f2e28
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
 -/
 import Mathlib.Init.Core
 import Mathlib.Init.Data.Prod

Dependencies

1 files ported (100.0%)
319 lines ported (100.0%)

All dependencies are ported!