data.finset.prodMathlib.Data.Finset.Prod

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)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(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)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -372,7 +372,7 @@ theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s
 #print Finset.product_inter_product /-
 theorem product_inter_product [DecidableEq α] [DecidableEq β] :
     s ×ˢ t ∩ s' ×ˢ t' = (s ∩ s') ×ˢ (t ∩ t') := by ext ⟨x, y⟩;
-  simp only [and_assoc', and_left_comm, mem_inter, mem_product]
+  simp only [and_assoc, and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
 -/
 
Diff
@@ -242,7 +242,7 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
   · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
     constructor <;> intro h <;> use h.1
     simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
-    cases h.2 <;> · try simp at h_1 ; simp [h_1]
+    cases h.2 <;> · try simp at h_1; simp [h_1]
   · apply Finset.disjoint_filter_filter'
     exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
Diff
@@ -187,7 +187,8 @@ theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset 
 /-- See also `finset.sup_product_left`. -/
 @[simp]
 theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
-    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by classical
+    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
+  classical simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion]
 #align finset.product_bUnion Finset.product_biUnion
 -/
 
@@ -235,7 +236,15 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1 ↔ q x.2).card =
       (s.filterₓ p).card * (t.filterₓ q).card +
         (s.filterₓ (Not ∘ p)).card * (t.filterₓ (Not ∘ q)).card :=
-  by classical
+  by
+  classical
+  rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
+  · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
+    constructor <;> intro h <;> use h.1
+    simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
+    cases h.2 <;> · try simp at h_1 ; simp [h_1]
+  · apply Finset.disjoint_filter_filter'
+    exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
 -/
 
Diff
@@ -187,8 +187,7 @@ theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset 
 /-- See also `finset.sup_product_left`. -/
 @[simp]
 theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
-    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
-  classical simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion]
+    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by classical
 #align finset.product_bUnion Finset.product_biUnion
 -/
 
@@ -236,15 +235,7 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1 ↔ q x.2).card =
       (s.filterₓ p).card * (t.filterₓ q).card +
         (s.filterₓ (Not ∘ p)).card * (t.filterₓ (Not ∘ q)).card :=
-  by
-  classical
-  rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
-  · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
-    constructor <;> intro h <;> use h.1
-    simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
-    cases h.2 <;> · try simp at h_1 ; simp [h_1]
-  · apply Finset.disjoint_filter_filter'
-    exact (disjoint_compl_right.inf_left _).inf_right _
+  by classical
 #align finset.filter_product_card Finset.filter_product_card
 -/
 
Diff
@@ -148,7 +148,7 @@ theorem product_subset_product_right (ht : t ⊆ t') : s ×ˢ t ⊆ s ×ˢ t' :=
 #print Finset.map_swap_product /-
 theorem map_swap_product (s : Finset α) (t : Finset β) :
     (t ×ˢ s).map ⟨Prod.swap, Prod.swap_injective⟩ = s ×ˢ t :=
-  coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
+  coe_injective <| by push_cast; exact Set.image_swap_prod _ _
 #align finset.map_swap_product Finset.map_swap_product
 -/
 
@@ -158,7 +158,7 @@ theorem map_swap_product (s : Finset α) (t : Finset β) :
 @[simp]
 theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     (t ×ˢ s).image Prod.swap = s ×ˢ t :=
-  coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
+  coe_injective <| by push_cast; exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 -/
 
@@ -548,7 +548,7 @@ theorem diag_inter : (s ∩ t).diag = s.diag ∩ t.diag :=
 
 #print Finset.offDiag_inter /-
 theorem offDiag_inter : (s ∩ t).offDiag = s.offDiag ∩ t.offDiag :=
-  coe_injective <| by push_cast ; exact Set.offDiag_inter _ _
+  coe_injective <| by push_cast; exact Set.offDiag_inter _ _
 #align finset.off_diag_inter Finset.offDiag_inter
 -/
 
@@ -565,7 +565,7 @@ variable {s t}
 #print Finset.offDiag_union /-
 theorem offDiag_union (h : Disjoint s t) :
     (s ∪ t).offDiag = s.offDiag ∪ t.offDiag ∪ s ×ˢ t ∪ t ×ˢ s :=
-  coe_injective <| by push_cast ; exact Set.offDiag_union (disjoint_coe.2 h)
+  coe_injective <| by push_cast; exact Set.offDiag_union (disjoint_coe.2 h)
 #align finset.off_diag_union Finset.offDiag_union
 -/
 
Diff
@@ -3,7 +3,7 @@ Copyright (c) 2017 Microsoft Corporation. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl, Mario Carneiro, Oliver Nash
 -/
-import Mathbin.Data.Finset.Card
+import Data.Finset.Card
 
 #align_import data.finset.prod from "leanprover-community/mathlib"@"e04043d6bf7264a3c84bc69711dc354958ca4516"
 
Diff
@@ -2,14 +2,11 @@
 Copyright (c) 2017 Microsoft Corporation. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl, Mario Carneiro, Oliver Nash
-
-! This file was ported from Lean 3 source module data.finset.prod
-! leanprover-community/mathlib commit e04043d6bf7264a3c84bc69711dc354958ca4516
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.Finset.Card
 
+#align_import data.finset.prod from "leanprover-community/mathlib"@"e04043d6bf7264a3c84bc69711dc354958ca4516"
+
 /-!
 # Finsets in product types
 
Diff
@@ -49,40 +49,49 @@ protected def product (s : Finset α) (t : Finset β) : Finset (α × β) :=
 #align finset.product Finset.product
 -/
 
--- mathport name: finset.product
 infixr:82
   " ×ˢ " =>-- This notation binds more strongly than (pre)images, unions and intersections.
   Finset.product
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_val /-
 @[simp]
 theorem product_val : (s ×ˢ t).1 = s.1 ×ˢ t.1 :=
   rfl
 #align finset.product_val Finset.product_val
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.mem_product /-
 @[simp]
 theorem mem_product {p : α × β} : p ∈ s ×ˢ t ↔ p.1 ∈ s ∧ p.2 ∈ t :=
   mem_product
 #align finset.mem_product Finset.mem_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.mk_mem_product /-
 theorem mk_mem_product (ha : a ∈ s) (hb : b ∈ t) : (a, b) ∈ s ×ˢ t :=
   mem_product.2 ⟨ha, hb⟩
 #align finset.mk_mem_product Finset.mk_mem_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.coe_product /-
 @[simp, norm_cast]
 theorem coe_product (s : Finset α) (t : Finset β) : (↑(s ×ˢ t) : Set (α × β)) = s ×ˢ t :=
   Set.ext fun x => Finset.mem_product
 #align finset.coe_product Finset.coe_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.subset_product_image_fst /-
 theorem subset_product_image_fst [DecidableEq α] : (s ×ˢ t).image Prod.fst ⊆ s := fun i => by
   simp (config := { contextual := true }) [mem_image]
 #align finset.subset_product_image_fst Finset.subset_product_image_fst
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 #print Finset.subset_product_image_snd /-
@@ -92,9 +101,11 @@ theorem subset_product_image_snd [DecidableEq β] : (s ×ˢ t).image Prod.snd 
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_image_fst /-
 theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s := by
   ext i; simp [mem_image, ht.bex]
 #align finset.product_image_fst Finset.product_image_fst
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 #print Finset.product_image_snd /-
@@ -104,22 +115,28 @@ theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.subset_product /-
 theorem subset_product [DecidableEq α] [DecidableEq β] {s : Finset (α × β)} :
     s ⊆ s.image Prod.fst ×ˢ s.image Prod.snd := fun p hp =>
   mem_product.2 ⟨mem_image_of_mem _ hp, mem_image_of_mem _ hp⟩
 #align finset.subset_product Finset.subset_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_subset_product /-
 theorem product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s ×ˢ t ⊆ s' ×ˢ t' := fun ⟨x, y⟩ h =>
   mem_product.2 ⟨hs (mem_product.1 h).1, ht (mem_product.1 h).2⟩
 #align finset.product_subset_product Finset.product_subset_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_subset_product_left /-
 theorem product_subset_product_left (hs : s ⊆ s') : s ×ˢ t ⊆ s' ×ˢ t :=
   product_subset_product hs (Subset.refl _)
 #align finset.product_subset_product_left Finset.product_subset_product_left
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -131,64 +148,80 @@ theorem product_subset_product_right (ht : t ⊆ t') : s ×ˢ t ⊆ s ×ˢ t' :=
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.map_swap_product /-
 theorem map_swap_product (s : Finset α) (t : Finset β) :
     (t ×ˢ s).map ⟨Prod.swap, Prod.swap_injective⟩ = s ×ˢ t :=
   coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.map_swap_product Finset.map_swap_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.image_swap_product /-
 @[simp]
 theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     (t ×ˢ s).image Prod.swap = s ×ˢ t :=
   coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_eq_biUnion /-
 theorem product_eq_biUnion [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     s ×ˢ t = s.biUnion fun a => t.image fun b => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion Finset.product_eq_biUnion
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_eq_biUnion_right /-
 theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     s ×ˢ t = t.biUnion fun b => s.image fun a => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion_right Finset.product_eq_biUnion_right
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_biUnion /-
 /-- See also `finset.sup_product_left`. -/
 @[simp]
 theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
     (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
   classical simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion]
 #align finset.product_bUnion Finset.product_biUnion
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.card_product /-
 @[simp]
 theorem card_product (s : Finset α) (t : Finset β) : card (s ×ˢ t) = card s * card t :=
   Multiset.card_product _ _
 #align finset.card_product Finset.card_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.filter_product /-
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1 ∧ q x.2) = s.filterₓ p ×ˢ t.filterₓ q :=
   by
   ext ⟨a, b⟩; simp only [mem_filter, mem_product]
   exact and_and_and_comm (a ∈ s) (b ∈ t) (p a) (q b)
 #align finset.filter_product Finset.filter_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.filter_product_left /-
 theorem filter_product_left (p : α → Prop) [DecidablePred p] :
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1) = s.filterₓ p ×ˢ t := by
   simpa using filter_product p fun _ => True
 #align finset.filter_product_left Finset.filter_product_left
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -200,6 +233,7 @@ theorem filter_product_right (q : β → Prop) [DecidablePred q] :
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.filter_product_card /-
 theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q : β → Prop)
     [DecidablePred p] [DecidablePred q] :
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1 ↔ q x.2).card =
@@ -215,6 +249,7 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
   · apply Finset.disjoint_filter_filter'
     exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 #print Finset.empty_product /-
@@ -224,47 +259,61 @@ theorem empty_product (t : Finset β) : (∅ : Finset α) ×ˢ t = ∅ :=
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_empty /-
 theorem product_empty (s : Finset α) : s ×ˢ (∅ : Finset β) = ∅ :=
   eq_empty_of_forall_not_mem fun x h => (Finset.mem_product.1 h).2
 #align finset.product_empty Finset.product_empty
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.Nonempty.product /-
 theorem Nonempty.product (hs : s.Nonempty) (ht : t.Nonempty) : (s ×ˢ t).Nonempty :=
   let ⟨x, hx⟩ := hs
   let ⟨y, hy⟩ := ht
   ⟨(x, y), mem_product.2 ⟨hx, hy⟩⟩
 #align finset.nonempty.product Finset.Nonempty.product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.Nonempty.fst /-
 theorem Nonempty.fst (h : (s ×ˢ t).Nonempty) : s.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.1, (mem_product.1 hxy).1⟩
 #align finset.nonempty.fst Finset.Nonempty.fst
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.Nonempty.snd /-
 theorem Nonempty.snd (h : (s ×ˢ t).Nonempty) : t.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.2, (mem_product.1 hxy).2⟩
 #align finset.nonempty.snd Finset.Nonempty.snd
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.nonempty_product /-
 @[simp]
 theorem nonempty_product : (s ×ˢ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
   ⟨fun h => ⟨h.fst, h.snd⟩, fun h => h.1.product h.2⟩
 #align finset.nonempty_product Finset.nonempty_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_eq_empty /-
 @[simp]
 theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ˢ t = ∅ ↔ s = ∅ ∨ t = ∅ := by
   rw [← not_nonempty_iff_eq_empty, nonempty_product, not_and_or, not_nonempty_iff_eq_empty,
     not_nonempty_iff_eq_empty]
 #align finset.product_eq_empty Finset.product_eq_empty
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.singleton_product /-
 @[simp]
 theorem singleton_product {a : α} : ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ :=
   by ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.singleton_product Finset.singleton_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 #print Finset.product_singleton /-
@@ -275,72 +324,90 @@ theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.singleton_product_singleton /-
 theorem singleton_product_singleton {a : α} {b : β} :
     ({a} : Finset α) ×ˢ ({b} : Finset β) = {(a, b)} := by
   simp only [product_singleton, Function.Embedding.coeFn_mk, map_singleton]
 #align finset.singleton_product_singleton Finset.singleton_product_singleton
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.union_product /-
 @[simp]
 theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s ×ˢ t ∪ s' ×ˢ t := by
   ext ⟨x, y⟩; simp only [or_and_right, mem_union, mem_product]
 #align finset.union_product Finset.union_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_union /-
 @[simp]
 theorem product_union [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∪ t') = s ×ˢ t ∪ s ×ˢ t' := by
   ext ⟨x, y⟩; simp only [and_or_left, mem_union, mem_product]
 #align finset.product_union Finset.product_union
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.inter_product /-
 theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ˢ t = s ×ˢ t ∩ s' ×ˢ t := by
   ext ⟨x, y⟩; simp only [← and_and_right, mem_inter, mem_product]
 #align finset.inter_product Finset.inter_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_inter /-
 theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s ×ˢ t ∩ s ×ˢ t' := by
   ext ⟨x, y⟩; simp only [← and_and_left, mem_inter, mem_product]
 #align finset.product_inter Finset.product_inter
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_inter_product /-
 theorem product_inter_product [DecidableEq α] [DecidableEq β] :
     s ×ˢ t ∩ s' ×ˢ t' = (s ∩ s') ×ˢ (t ∩ t') := by ext ⟨x, y⟩;
   simp only [and_assoc', and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.disjoint_product /-
 theorem disjoint_product : Disjoint (s ×ˢ t) (s' ×ˢ t') ↔ Disjoint s s' ∨ Disjoint t t' := by
   simp_rw [← disjoint_coe, coe_product, Set.disjoint_prod]
 #align finset.disjoint_product Finset.disjoint_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.disjUnion_product /-
 @[simp]
 theorem disjUnion_product (hs : Disjoint s s') :
     s.disjUnion s' hs ×ˢ t = (s ×ˢ t).disjUnion (s' ×ˢ t) (disjoint_product.mpr <| Or.inl hs) :=
   eq_of_veq <| Multiset.add_product _ _ _
 #align finset.disj_union_product Finset.disjUnion_product
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_disjUnion /-
 @[simp]
 theorem product_disjUnion (ht : Disjoint t t') :
     s ×ˢ t.disjUnion t' ht = (s ×ˢ t).disjUnion (s ×ˢ t') (disjoint_product.mpr <| Or.inr ht) :=
   eq_of_veq <| Multiset.product_add _ _ _
 #align finset.product_disj_union Finset.product_disjUnion
+-/
 
 end Prod
 
@@ -447,47 +514,63 @@ theorem offDiag_empty : (∅ : Finset α).offDiag = ∅ :=
 -/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.diag_union_offDiag /-
 @[simp]
 theorem diag_union_offDiag : s.diag ∪ s.offDiag = s ×ˢ s :=
   filter_union_filter_neg_eq _ _
 #align finset.diag_union_off_diag Finset.diag_union_offDiag
+-/
 
+#print Finset.disjoint_diag_offDiag /-
 @[simp]
 theorem disjoint_diag_offDiag : Disjoint s.diag s.offDiag :=
   disjoint_filter_filter_neg _ _ _
 #align finset.disjoint_diag_off_diag Finset.disjoint_diag_offDiag
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_sdiff_diag /-
 theorem product_sdiff_diag : s ×ˢ s \ s.diag = s.offDiag := by
   rw [← diag_union_off_diag, union_comm, union_sdiff_self,
     sdiff_eq_self_of_disjoint (disjoint_diag_off_diag _).symm]
 #align finset.product_sdiff_diag Finset.product_sdiff_diag
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_sdiff_offDiag /-
 theorem product_sdiff_offDiag : s ×ˢ s \ s.offDiag = s.diag := by
   rw [← diag_union_off_diag, union_sdiff_self, sdiff_eq_self_of_disjoint (disjoint_diag_off_diag _)]
 #align finset.product_sdiff_off_diag Finset.product_sdiff_offDiag
+-/
 
+#print Finset.diag_inter /-
 theorem diag_inter : (s ∩ t).diag = s.diag ∩ t.diag :=
   ext fun x => by simpa only [mem_diag, mem_inter] using and_and_right _ _ _
 #align finset.diag_inter Finset.diag_inter
+-/
 
+#print Finset.offDiag_inter /-
 theorem offDiag_inter : (s ∩ t).offDiag = s.offDiag ∩ t.offDiag :=
   coe_injective <| by push_cast ; exact Set.offDiag_inter _ _
 #align finset.off_diag_inter Finset.offDiag_inter
+-/
 
+#print Finset.diag_union /-
 theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag := by ext ⟨i, j⟩;
   simp only [mem_diag, mem_union, or_and_right]
 #align finset.diag_union Finset.diag_union
+-/
 
 variable {s t}
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.offDiag_union /-
 theorem offDiag_union (h : Disjoint s t) :
     (s ∪ t).offDiag = s.offDiag ∪ t.offDiag ∪ s ×ˢ t ∪ t ×ˢ s :=
   coe_injective <| by push_cast ; exact Set.offDiag_union (disjoint_coe.2 h)
 #align finset.off_diag_union Finset.offDiag_union
+-/
 
 variable (a : α)
 
@@ -503,16 +586,20 @@ theorem diag_singleton : ({a} : Finset α).diag = {(a, a)} := by
 #align finset.diag_singleton Finset.diag_singleton
 -/
 
+#print Finset.diag_insert /-
 theorem diag_insert : (insert a s).diag = insert (a, a) s.diag := by
   rw [insert_eq, insert_eq, diag_union, diag_singleton]
 #align finset.diag_insert Finset.diag_insert
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.offDiag_insert /-
 theorem offDiag_insert (has : a ∉ s) : (insert a s).offDiag = s.offDiag ∪ {a} ×ˢ s ∪ s ×ˢ {a} := by
   rw [insert_eq, union_comm, off_diag_union (disjoint_singleton_right.2 has), off_diag_singleton,
     union_empty, union_right_comm]
 #align finset.off_diag_insert Finset.offDiag_insert
+-/
 
 end Diag
 
Diff
@@ -207,13 +207,13 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
         (s.filterₓ (Not ∘ p)).card * (t.filterₓ (Not ∘ q)).card :=
   by
   classical
-    rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
-    · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
-      constructor <;> intro h <;> use h.1
-      simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
-      cases h.2 <;> · try simp at h_1 ; simp [h_1]
-    · apply Finset.disjoint_filter_filter'
-      exact (disjoint_compl_right.inf_left _).inf_right _
+  rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
+  · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
+    constructor <;> intro h <;> use h.1
+    simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
+    cases h.2 <;> · try simp at h_1 ; simp [h_1]
+  · apply Finset.disjoint_filter_filter'
+    exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
Diff
@@ -211,7 +211,7 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
     · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
       constructor <;> intro h <;> use h.1
       simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
-      cases h.2 <;> · try simp at h_1; simp [h_1]
+      cases h.2 <;> · try simp at h_1 ; simp [h_1]
     · apply Finset.disjoint_filter_filter'
       exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
Diff
@@ -267,10 +267,12 @@ theorem singleton_product {a : α} : ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk
 #align finset.singleton_product Finset.singleton_product
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
+#print Finset.product_singleton /-
 @[simp]
 theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
   ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.product_singleton Finset.product_singleton
+-/
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem singleton_product_singleton {a : α} {b : β} :
Diff
@@ -54,12 +54,6 @@ infixr:82
   " ×ˢ " =>-- This notation binds more strongly than (pre)images, unions and intersections.
   Finset.product
 
-/- warning: finset.product_val -> Finset.product_val is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, Eq.{succ (max u1 u2)} (Multiset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.val.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) (Multiset.product.{u1, u2} α β (Finset.val.{u1} α s) (Finset.val.{u2} β t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, Eq.{max (succ u2) (succ u1)} (Multiset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.val.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) (Multiset.product.{u2, u1} α β (Finset.val.{u2} α s) (Finset.val.{u1} β t))
-Case conversion may be inaccurate. Consider using '#align finset.product_val Finset.product_valₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
@@ -67,35 +61,17 @@ theorem product_val : (s ×ˢ t).1 = s.1 ×ˢ t.1 :=
   rfl
 #align finset.product_val Finset.product_val
 
-/- warning: finset.mem_product -> Finset.mem_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {p : Prod.{u1, u2} α β}, Iff (Membership.Mem.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasMem.{max u1 u2} (Prod.{u1, u2} α β)) p (Finset.product.{u1, u2} α β s t)) (And (Membership.Mem.{u1, u1} α (Finset.{u1} α) (Finset.hasMem.{u1} α) (Prod.fst.{u1, u2} α β p) s) (Membership.Mem.{u2, u2} β (Finset.{u2} β) (Finset.hasMem.{u2} β) (Prod.snd.{u1, u2} α β p) t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} {p : Prod.{u2, u1} α β}, Iff (Membership.mem.{max u2 u1, max u1 u2} (Prod.{u2, u1} α β) (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instMembershipFinset.{max u2 u1} (Prod.{u2, u1} α β)) p (Finset.product.{u2, u1} α β s t)) (And (Membership.mem.{u2, u2} α (Finset.{u2} α) (Finset.instMembershipFinset.{u2} α) (Prod.fst.{u2, u1} α β p) s) (Membership.mem.{u1, u1} β (Finset.{u1} β) (Finset.instMembershipFinset.{u1} β) (Prod.snd.{u2, u1} α β p) t))
-Case conversion may be inaccurate. Consider using '#align finset.mem_product Finset.mem_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem mem_product {p : α × β} : p ∈ s ×ˢ t ↔ p.1 ∈ s ∧ p.2 ∈ t :=
   mem_product
 #align finset.mem_product Finset.mem_product
 
-/- warning: finset.mk_mem_product -> Finset.mk_mem_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {a : α} {b : β}, (Membership.Mem.{u1, u1} α (Finset.{u1} α) (Finset.hasMem.{u1} α) a s) -> (Membership.Mem.{u2, u2} β (Finset.{u2} β) (Finset.hasMem.{u2} β) b t) -> (Membership.Mem.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasMem.{max u1 u2} (Prod.{u1, u2} α β)) (Prod.mk.{u1, u2} α β a b) (Finset.product.{u1, u2} α β s t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} {a : α} {b : β}, (Membership.mem.{u2, u2} α (Finset.{u2} α) (Finset.instMembershipFinset.{u2} α) a s) -> (Membership.mem.{u1, u1} β (Finset.{u1} β) (Finset.instMembershipFinset.{u1} β) b t) -> (Membership.mem.{max u1 u2, max u1 u2} (Prod.{u2, u1} α β) (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instMembershipFinset.{max u2 u1} (Prod.{u2, u1} α β)) (Prod.mk.{u2, u1} α β a b) (Finset.product.{u2, u1} α β s t))
-Case conversion may be inaccurate. Consider using '#align finset.mk_mem_product Finset.mk_mem_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem mk_mem_product (ha : a ∈ s) (hb : b ∈ t) : (a, b) ∈ s ×ˢ t :=
   mem_product.2 ⟨ha, hb⟩
 #align finset.mk_mem_product Finset.mk_mem_product
 
-/- warning: finset.coe_product -> Finset.coe_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Set.{max u1 u2} (Prod.{u1, u2} α β)) ((fun (a : Type.{max u1 u2}) (b : Type.{max u1 u2}) [self : HasLiftT.{succ (max u1 u2), succ (max u1 u2)} a b] => self.0) (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Set.{max u1 u2} (Prod.{u1, u2} α β)) (HasLiftT.mk.{succ (max u1 u2), succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Set.{max u1 u2} (Prod.{u1, u2} α β)) (CoeTCₓ.coe.{succ (max u1 u2), succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Set.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.Set.hasCoeT.{max u1 u2} (Prod.{u1, u2} α β)))) (Finset.product.{u1, u2} α β s t)) (Set.prod.{u1, u2} α β ((fun (a : Type.{u1}) (b : Type.{u1}) [self : HasLiftT.{succ u1, succ u1} a b] => self.0) (Finset.{u1} α) (Set.{u1} α) (HasLiftT.mk.{succ u1, succ u1} (Finset.{u1} α) (Set.{u1} α) (CoeTCₓ.coe.{succ u1, succ u1} (Finset.{u1} α) (Set.{u1} α) (Finset.Set.hasCoeT.{u1} α))) s) ((fun (a : Type.{u2}) (b : Type.{u2}) [self : HasLiftT.{succ u2, succ u2} a b] => self.0) (Finset.{u2} β) (Set.{u2} β) (HasLiftT.mk.{succ u2, succ u2} (Finset.{u2} β) (Set.{u2} β) (CoeTCₓ.coe.{succ u2, succ u2} (Finset.{u2} β) (Set.{u2} β) (Finset.Set.hasCoeT.{u2} β))) t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β), Eq.{max (succ u2) (succ u1)} (Set.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.toSet.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) (Set.prod.{u2, u1} α β (Finset.toSet.{u2} α s) (Finset.toSet.{u1} β t))
-Case conversion may be inaccurate. Consider using '#align finset.coe_product Finset.coe_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp, norm_cast]
@@ -103,12 +79,6 @@ theorem coe_product (s : Finset α) (t : Finset β) : (↑(s ×ˢ t) : Set (α 
   Set.ext fun x => Finset.mem_product
 #align finset.coe_product Finset.coe_product
 
-/- warning: finset.subset_product_image_fst -> Finset.subset_product_image_fst is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α], HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) (Finset.image.{max u1 u2, u1} (Prod.{u1, u2} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) s
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α], HasSubset.Subset.{u2} (Finset.{u2} α) (Finset.instHasSubsetFinset.{u2} α) (Finset.image.{max u1 u2, u2} (Prod.{u2, u1} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) s
-Case conversion may be inaccurate. Consider using '#align finset.subset_product_image_fst Finset.subset_product_image_fstₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem subset_product_image_fst [DecidableEq α] : (s ×ˢ t).image Prod.fst ⊆ s := fun i => by
   simp (config := { contextual := true }) [mem_image]
@@ -121,12 +91,6 @@ theorem subset_product_image_snd [DecidableEq β] : (s ×ˢ t).image Prod.snd 
 #align finset.subset_product_image_snd Finset.subset_product_image_snd
 -/
 
-/- warning: finset.product_image_fst -> Finset.product_image_fst is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α], (Finset.Nonempty.{u2} β t) -> (Eq.{succ u1} (Finset.{u1} α) (Finset.image.{max u1 u2, u1} (Prod.{u1, u2} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) s)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α], (Finset.Nonempty.{u1} β t) -> (Eq.{succ u2} (Finset.{u2} α) (Finset.image.{max u1 u2, u2} (Prod.{u2, u1} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) s)
-Case conversion may be inaccurate. Consider using '#align finset.product_image_fst Finset.product_image_fstₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s := by
   ext i; simp [mem_image, ht.bex]
@@ -139,36 +103,18 @@ theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image
 #align finset.product_image_snd Finset.product_image_snd
 -/
 
-/- warning: finset.subset_product -> Finset.subset_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] {s : Finset.{max u1 u2} (Prod.{u1, u2} α β)}, HasSubset.Subset.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasSubset.{max u1 u2} (Prod.{u1, u2} α β)) s (Finset.product.{u1, u2} α β (Finset.image.{max u1 u2, u1} (Prod.{u1, u2} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u1, u2} α β) s) (Finset.image.{max u1 u2, u2} (Prod.{u1, u2} α β) β (fun (a : β) (b : β) => _inst_2 a b) (Prod.snd.{u1, u2} α β) s))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β] {s : Finset.{max u1 u2} (Prod.{u2, u1} α β)}, HasSubset.Subset.{max u2 u1} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instHasSubsetFinset.{max u2 u1} (Prod.{u2, u1} α β)) s (Finset.product.{u2, u1} α β (Finset.image.{max u1 u2, u2} (Prod.{u2, u1} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u2, u1} α β) s) (Finset.image.{max u1 u2, u1} (Prod.{u2, u1} α β) β (fun (a : β) (b : β) => _inst_2 a b) (Prod.snd.{u2, u1} α β) s))
-Case conversion may be inaccurate. Consider using '#align finset.subset_product Finset.subset_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem subset_product [DecidableEq α] [DecidableEq β] {s : Finset (α × β)} :
     s ⊆ s.image Prod.fst ×ˢ s.image Prod.snd := fun p hp =>
   mem_product.2 ⟨mem_image_of_mem _ hp, mem_image_of_mem _ hp⟩
 #align finset.subset_product Finset.subset_product
 
-/- warning: finset.product_subset_product -> Finset.product_subset_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β}, (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) s s') -> (HasSubset.Subset.{u2} (Finset.{u2} β) (Finset.hasSubset.{u2} β) t t') -> (HasSubset.Subset.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasSubset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β} {t' : Finset.{u1} β}, (HasSubset.Subset.{u2} (Finset.{u2} α) (Finset.instHasSubsetFinset.{u2} α) s s') -> (HasSubset.Subset.{u1} (Finset.{u1} β) (Finset.instHasSubsetFinset.{u1} β) t t') -> (HasSubset.Subset.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instHasSubsetFinset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t'))
-Case conversion may be inaccurate. Consider using '#align finset.product_subset_product Finset.product_subset_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s ×ˢ t ⊆ s' ×ˢ t' := fun ⟨x, y⟩ h =>
   mem_product.2 ⟨hs (mem_product.1 h).1, ht (mem_product.1 h).2⟩
 #align finset.product_subset_product Finset.product_subset_product
 
-/- warning: finset.product_subset_product_left -> Finset.product_subset_product_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β}, (HasSubset.Subset.{u1} (Finset.{u1} α) (Finset.hasSubset.{u1} α) s s') -> (HasSubset.Subset.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasSubset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β}, (HasSubset.Subset.{u2} (Finset.{u2} α) (Finset.instHasSubsetFinset.{u2} α) s s') -> (HasSubset.Subset.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instHasSubsetFinset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t))
-Case conversion may be inaccurate. Consider using '#align finset.product_subset_product_left Finset.product_subset_product_leftₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_subset_product_left (hs : s ⊆ s') : s ×ˢ t ⊆ s' ×ˢ t :=
@@ -183,12 +129,6 @@ theorem product_subset_product_right (ht : t ⊆ t') : s ×ˢ t ⊆ s ×ˢ t' :=
 #align finset.product_subset_product_right Finset.product_subset_product_right
 -/
 
-/- warning: finset.map_swap_product -> Finset.map_swap_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.map.{max u2 u1, max u1 u2} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (Function.Embedding.mk.{succ (max u2 u1), succ (max u1 u2)} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (Prod.swap.{u2, u1} β α) (Prod.swap_injective.{u2, u1} β α)) (Finset.product.{u2, u1} β α t s)) (Finset.product.{u1, u2} α β s t)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β), Eq.{max (succ u2) (succ u1)} (Finset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.map.{max u2 u1, max u2 u1} (Prod.{u1, u2} β α) (Prod.{u2, u1} α β) (Function.Embedding.mk.{succ (max u2 u1), succ (max u2 u1)} (Prod.{u1, u2} β α) (Prod.{u2, u1} α β) (Prod.swap.{u1, u2} β α) (Prod.swap_injective.{u2, u1} β α)) (Finset.product.{u1, u2} β α t s)) (Finset.product.{u2, u1} α β s t)
-Case conversion may be inaccurate. Consider using '#align finset.map_swap_product Finset.map_swap_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem map_swap_product (s : Finset α) (t : Finset β) :
@@ -196,12 +136,6 @@ theorem map_swap_product (s : Finset α) (t : Finset β) :
   coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.map_swap_product Finset.map_swap_product
 
-/- warning: finset.image_swap_product -> Finset.image_swap_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.image.{max u2 u1, max u1 u2} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (Prod.swap.{u2, u1} β α) (Finset.product.{u2, u1} β α t s)) (Finset.product.{u1, u2} α β s t)
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.image.{max u1 u2, max u1 u2} (Prod.{u2, u1} β α) (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (Prod.swap.{u2, u1} β α) (Finset.product.{u2, u1} β α s _inst_2)) (Finset.product.{u1, u2} α β _inst_2 s)
-Case conversion may be inaccurate. Consider using '#align finset.image_swap_product Finset.image_swap_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
@@ -210,12 +144,6 @@ theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t
   coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
-/- warning: finset.product_eq_bUnion -> Finset.product_eq_biUnion is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.biUnion.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) s (fun (a : α) => Finset.image.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) t))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.biUnion.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) _inst_2 (fun (a : α) => Finset.image.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) s))
-Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion Finset.product_eq_biUnionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_eq_biUnion [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     s ×ˢ t = s.biUnion fun a => t.image fun b => (a, b) :=
@@ -224,12 +152,6 @@ theorem product_eq_biUnion [DecidableEq α] [DecidableEq β] (s : Finset α) (t
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion Finset.product_eq_biUnion
 
-/- warning: finset.product_eq_bUnion_right -> Finset.product_eq_biUnion_right is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.biUnion.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) t (fun (b : β) => Finset.image.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) s))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.biUnion.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) s (fun (b : β) => Finset.image.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) _inst_2))
-Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion_right Finset.product_eq_biUnion_rightₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     s ×ˢ t = t.biUnion fun b => s.image fun a => (a, b) :=
@@ -238,12 +160,6 @@ theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset 
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion_right Finset.product_eq_biUnion_right
 
-/- warning: finset.product_bUnion -> Finset.product_biUnion is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u1} α) (t : Finset.{u2} β) (f : (Prod.{u1, u2} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.biUnion.{max u1 u2, u3} (Prod.{u1, u2} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u1, u2} α β s t) f) (Finset.biUnion.{u1, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.biUnion.{u2, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u1, u2} α β a b))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u2} α) (t : Finset.{u1} β) (f : (Prod.{u2, u1} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.biUnion.{max u2 u1, u3} (Prod.{u2, u1} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u2, u1} α β s t) f) (Finset.biUnion.{u2, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.biUnion.{u1, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u2, u1} α β a b))))
-Case conversion may be inaccurate. Consider using '#align finset.product_bUnion Finset.product_biUnionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /-- See also `finset.sup_product_left`. -/
 @[simp]
@@ -252,24 +168,12 @@ theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α
   classical simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion]
 #align finset.product_bUnion Finset.product_biUnion
 
-/- warning: finset.card_product -> Finset.card_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{1} Nat (Finset.card.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α s) (Finset.card.{u2} β t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β), Eq.{1} Nat (Finset.card.{max u1 u2} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α s) (Finset.card.{u1} β t))
-Case conversion may be inaccurate. Consider using '#align finset.card_product Finset.card_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem card_product (s : Finset α) (t : Finset β) : card (s ×ˢ t) = card s * card t :=
   Multiset.card_product _ _
 #align finset.card_product Finset.card_product
 
-/- warning: finset.filter_product -> Finset.filter_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u2} β q], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.filter.{max u1 u2} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => And (p (Prod.fst.{u1, u2} α β x)) (q (Prod.snd.{u1, u2} α β x))) (fun (a : Prod.{u1, u2} α β) => And.decidable (p (Prod.fst.{u1, u2} α β a)) (q (Prod.snd.{u1, u2} α β a)) (_inst_1 (Prod.fst.{u1, u2} α β a)) (_inst_2 (Prod.snd.{u1, u2} α β a))) (Finset.product.{u1, u2} α β s t)) (Finset.product.{u1, u2} α β (Finset.filter.{u1} α p (fun (a : α) => _inst_1 a) s) (Finset.filter.{u2} β q (fun (a : β) => _inst_2 a) t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u2} α p] [_inst_2 : DecidablePred.{succ u1} β q], Eq.{max (succ u2) (succ u1)} (Finset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.filter.{max u2 u1} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => And (p (Prod.fst.{u2, u1} α β x)) (q (Prod.snd.{u2, u1} α β x))) (fun (a : Prod.{u2, u1} α β) => instDecidableAnd (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (_inst_1 (Prod.fst.{u2, u1} α β a)) (_inst_2 (Prod.snd.{u2, u1} α β a))) (Finset.product.{u2, u1} α β s t)) (Finset.product.{u2, u1} α β (Finset.filter.{u2} α p (fun (a : α) => _inst_1 a) s) (Finset.filter.{u1} β q (fun (a : β) => _inst_2 a) t))
-Case conversion may be inaccurate. Consider using '#align finset.filter_product Finset.filter_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
@@ -279,12 +183,6 @@ theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [De
   exact and_and_and_comm (a ∈ s) (b ∈ t) (p a) (q b)
 #align finset.filter_product Finset.filter_product
 
-/- warning: finset.filter_product_left -> Finset.filter_product_left is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u1} α p], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.filter.{max u1 u2} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => p (Prod.fst.{u1, u2} α β x)) (fun (a : Prod.{u1, u2} α β) => _inst_1 (Prod.fst.{u1, u2} α β a)) (Finset.product.{u1, u2} α β s t)) (Finset.product.{u1, u2} α β (Finset.filter.{u1} α p (fun (a : α) => _inst_1 a) s) t)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} (p : α -> Prop) [_inst_1 : DecidablePred.{succ u2} α p], Eq.{max (succ u2) (succ u1)} (Finset.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.filter.{max u2 u1} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => p (Prod.fst.{u2, u1} α β x)) (fun (a : Prod.{u2, u1} α β) => _inst_1 (Prod.fst.{u2, u1} α β a)) (Finset.product.{u2, u1} α β s t)) (Finset.product.{u2, u1} α β (Finset.filter.{u2} α p (fun (a : α) => _inst_1 a) s) t)
-Case conversion may be inaccurate. Consider using '#align finset.filter_product_left Finset.filter_product_leftₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem filter_product_left (p : α → Prop) [DecidablePred p] :
@@ -301,12 +199,6 @@ theorem filter_product_right (q : β → Prop) [DecidablePred q] :
 #align finset.filter_product_right Finset.filter_product_right
 -/
 
-/- warning: finset.filter_product_card -> Finset.filter_product_card is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α) (t : Finset.{u2} β) (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u2} β q], Eq.{1} Nat (Finset.card.{max u1 u2} (Prod.{u1, u2} α β) (Finset.filter.{max u1 u2} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => Iff (p (Prod.fst.{u1, u2} α β x)) (q (Prod.snd.{u1, u2} α β x))) (fun (a : Prod.{u1, u2} α β) => Iff.decidable (p (Prod.fst.{u1, u2} α β a)) (q (Prod.snd.{u1, u2} α β a)) (_inst_1 (Prod.fst.{u1, u2} α β a)) (_inst_2 (Prod.snd.{u1, u2} α β a))) (Finset.product.{u1, u2} α β s t))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (Finset.filter.{u1} α p (fun (a : α) => _inst_1 a) s)) (Finset.card.{u2} β (Finset.filter.{u2} β q (fun (a : β) => _inst_2 a) t))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (Finset.filter.{u1} α (Function.comp.{succ u1, 1, 1} α Prop Prop Not p) (fun (a : α) => Not.decidable (p a) (_inst_1 a)) s)) (Finset.card.{u2} β (Finset.filter.{u2} β (Function.comp.{succ u2, 1, 1} β Prop Prop Not q) (fun (a : β) => Not.decidable (q a) (_inst_2 a)) t))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β) (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u2} α p] [_inst_2 : DecidablePred.{succ u1} β q], Eq.{1} Nat (Finset.card.{max u2 u1} (Prod.{u2, u1} α β) (Finset.filter.{max u2 u1} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => Eq.{1} Prop (p (Prod.fst.{u2, u1} α β x)) (q (Prod.snd.{u2, u1} α β x))) (fun (a : Prod.{u2, u1} α β) => instDecidableEqProp (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (instDecidableIff (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (_inst_1 (Prod.fst.{u2, u1} α β a)) (_inst_2 (Prod.snd.{u2, u1} α β a)))) (Finset.product.{u2, u1} α β s t))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α p (fun (a : α) => _inst_1 a) s)) (Finset.card.{u1} β (Finset.filter.{u1} β q (fun (a : β) => _inst_2 a) t))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1938 : α) => Not (p x._@.Mathlib.Data.Finset.Prod._hyg.1938)) (fun (a : α) => instDecidableNot (p a) (_inst_1 a)) s)) (Finset.card.{u1} β (Finset.filter.{u1} β (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1954 : β) => Not (q x._@.Mathlib.Data.Finset.Prod._hyg.1954)) (fun (a : β) => instDecidableNot (q a) (_inst_2 a)) t))))
-Case conversion may be inaccurate. Consider using '#align finset.filter_product_card Finset.filter_product_cardₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q : β → Prop)
     [DecidablePred p] [DecidablePred q] :
@@ -331,23 +223,11 @@ theorem empty_product (t : Finset β) : (∅ : Finset α) ×ˢ t = ∅ :=
 #align finset.empty_product Finset.empty_product
 -/
 
-/- warning: finset.product_empty -> Finset.product_empty is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (EmptyCollection.emptyCollection.{u2} (Finset.{u2} β) (Finset.hasEmptyc.{u2} β))) (EmptyCollection.emptyCollection.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasEmptyc.{max u1 u2} (Prod.{u1, u2} α β)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α), Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s (EmptyCollection.emptyCollection.{u1} (Finset.{u1} β) (Finset.instEmptyCollectionFinset.{u1} β))) (EmptyCollection.emptyCollection.{max u2 u1} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instEmptyCollectionFinset.{max u2 u1} (Prod.{u2, u1} α β)))
-Case conversion may be inaccurate. Consider using '#align finset.product_empty Finset.product_emptyₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_empty (s : Finset α) : s ×ˢ (∅ : Finset β) = ∅ :=
   eq_empty_of_forall_not_mem fun x h => (Finset.mem_product.1 h).2
 #align finset.product_empty Finset.product_empty
 
-/- warning: finset.nonempty.product -> Finset.Nonempty.product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, (Finset.Nonempty.{u1} α s) -> (Finset.Nonempty.{u2} β t) -> (Finset.Nonempty.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, (Finset.Nonempty.{u2} α s) -> (Finset.Nonempty.{u1} β t) -> (Finset.Nonempty.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t))
-Case conversion may be inaccurate. Consider using '#align finset.nonempty.product Finset.Nonempty.productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem Nonempty.product (hs : s.Nonempty) (ht : t.Nonempty) : (s ×ˢ t).Nonempty :=
   let ⟨x, hx⟩ := hs
@@ -355,48 +235,24 @@ theorem Nonempty.product (hs : s.Nonempty) (ht : t.Nonempty) : (s ×ˢ t).Nonemp
   ⟨(x, y), mem_product.2 ⟨hx, hy⟩⟩
 #align finset.nonempty.product Finset.Nonempty.product
 
-/- warning: finset.nonempty.fst -> Finset.Nonempty.fst is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, (Finset.Nonempty.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) -> (Finset.Nonempty.{u1} α s)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, (Finset.Nonempty.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) -> (Finset.Nonempty.{u2} α s)
-Case conversion may be inaccurate. Consider using '#align finset.nonempty.fst Finset.Nonempty.fstₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem Nonempty.fst (h : (s ×ˢ t).Nonempty) : s.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.1, (mem_product.1 hxy).1⟩
 #align finset.nonempty.fst Finset.Nonempty.fst
 
-/- warning: finset.nonempty.snd -> Finset.Nonempty.snd is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, (Finset.Nonempty.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) -> (Finset.Nonempty.{u2} β t)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, (Finset.Nonempty.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) -> (Finset.Nonempty.{u1} β t)
-Case conversion may be inaccurate. Consider using '#align finset.nonempty.snd Finset.Nonempty.sndₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem Nonempty.snd (h : (s ×ˢ t).Nonempty) : t.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.2, (mem_product.1 hxy).2⟩
 #align finset.nonempty.snd Finset.Nonempty.snd
 
-/- warning: finset.nonempty_product -> Finset.nonempty_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, Iff (Finset.Nonempty.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t)) (And (Finset.Nonempty.{u1} α s) (Finset.Nonempty.{u2} β t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, Iff (Finset.Nonempty.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) (And (Finset.Nonempty.{u2} α s) (Finset.Nonempty.{u1} β t))
-Case conversion may be inaccurate. Consider using '#align finset.nonempty_product Finset.nonempty_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem nonempty_product : (s ×ˢ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
   ⟨fun h => ⟨h.fst, h.snd⟩, fun h => h.1.product h.2⟩
 #align finset.nonempty_product Finset.nonempty_product
 
-/- warning: finset.product_eq_empty -> Finset.product_eq_empty is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β}, Iff (Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (EmptyCollection.emptyCollection.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasEmptyc.{max u1 u2} (Prod.{u1, u2} α β)))) (Or (Eq.{succ u1} (Finset.{u1} α) s (EmptyCollection.emptyCollection.{u1} (Finset.{u1} α) (Finset.hasEmptyc.{u1} α))) (Eq.{succ u2} (Finset.{u2} β) t (EmptyCollection.emptyCollection.{u2} (Finset.{u2} β) (Finset.hasEmptyc.{u2} β))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β}, Iff (Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s t) (EmptyCollection.emptyCollection.{max u2 u1} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instEmptyCollectionFinset.{max u2 u1} (Prod.{u2, u1} α β)))) (Or (Eq.{succ u2} (Finset.{u2} α) s (EmptyCollection.emptyCollection.{u2} (Finset.{u2} α) (Finset.instEmptyCollectionFinset.{u2} α))) (Eq.{succ u1} (Finset.{u1} β) t (EmptyCollection.emptyCollection.{u1} (Finset.{u1} β) (Finset.instEmptyCollectionFinset.{u1} β))))
-Case conversion may be inaccurate. Consider using '#align finset.product_eq_empty Finset.product_eq_emptyₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ˢ t = ∅ ↔ s = ∅ ∨ t = ∅ := by
@@ -404,48 +260,24 @@ theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ˢ t = ∅ ↔ s
     not_nonempty_iff_eq_empty]
 #align finset.product_eq_empty Finset.product_eq_empty
 
-/- warning: finset.singleton_product -> Finset.singleton_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {t : Finset.{u2} β} {a : α}, Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.hasSingleton.{u1} α) a) t) (Finset.map.{u2, max u1 u2} β (Prod.{u1, u2} α β) (Function.Embedding.mk.{succ u2, succ (max u1 u2)} β (Prod.{u1, u2} α β) (Prod.mk.{u1, u2} α β a) (Prod.mk.inj_left.{u1, u2} α β a)) t)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {t : Finset.{u1} β} {a : α}, Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β (Singleton.singleton.{u2, u2} α (Finset.{u2} α) (Finset.instSingletonFinset.{u2} α) a) t) (Finset.map.{u1, max u1 u2} β (Prod.{u2, u1} α β) (Function.Embedding.mk.{succ u1, succ (max u1 u2)} β (Prod.{u2, u1} α β) (Prod.mk.{u2, u1} α β a) (Prod.mk.inj_left.{u1, u2} α β a)) t)
-Case conversion may be inaccurate. Consider using '#align finset.singleton_product Finset.singleton_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem singleton_product {a : α} : ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ :=
   by ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.singleton_product Finset.singleton_product
 
-/- warning: finset.product_singleton -> Finset.product_singleton is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {b : β}, Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (Singleton.singleton.{u2, u2} β (Finset.{u2} β) (Finset.hasSingleton.{u2} β) b)) (Finset.map.{u1, max u1 u2} α (Prod.{u1, u2} α β) (Function.Embedding.mk.{succ u1, succ (max u1 u2)} α (Prod.{u1, u2} α β) (fun (i : α) => Prod.mk.{u1, u2} α β i b) (Prod.mk.inj_right.{u1, u2} α β b)) s)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {b : β}, Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s (Singleton.singleton.{u1, u1} β (Finset.{u1} β) (Finset.instSingletonFinset.{u1} β) b)) (Finset.map.{u2, max u1 u2} α (Prod.{u2, u1} α β) (Function.Embedding.mk.{succ u2, succ (max u1 u2)} α (Prod.{u2, u1} α β) (fun (i : α) => Prod.mk.{u2, u1} α β i b) (Prod.mk.inj_right.{u1, u2} α β b)) s)
-Case conversion may be inaccurate. Consider using '#align finset.product_singleton Finset.product_singletonₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
   ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.product_singleton Finset.product_singleton
 
-/- warning: finset.singleton_product_singleton -> Finset.singleton_product_singleton is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {a : α} {b : β}, Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.hasSingleton.{u1} α) a) (Singleton.singleton.{u2, u2} β (Finset.{u2} β) (Finset.hasSingleton.{u2} β) b)) (Singleton.singleton.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasSingleton.{max u1 u2} (Prod.{u1, u2} α β)) (Prod.mk.{u1, u2} α β a b))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {a : α} {b : β}, Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β (Singleton.singleton.{u2, u2} α (Finset.{u2} α) (Finset.instSingletonFinset.{u2} α) a) (Singleton.singleton.{u1, u1} β (Finset.{u1} β) (Finset.instSingletonFinset.{u1} β) b)) (Singleton.singleton.{max u1 u2, max u2 u1} (Prod.{u2, u1} α β) (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instSingletonFinset.{max u2 u1} (Prod.{u2, u1} α β)) (Prod.mk.{u2, u1} α β a b))
-Case conversion may be inaccurate. Consider using '#align finset.singleton_product_singleton Finset.singleton_product_singletonₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem singleton_product_singleton {a : α} {b : β} :
     ({a} : Finset α) ×ˢ ({b} : Finset β) = {(a, b)} := by
   simp only [product_singleton, Function.Embedding.coeFn_mk, map_singleton]
 #align finset.singleton_product_singleton Finset.singleton_product_singleton
 
-/- warning: finset.union_product -> Finset.union_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s s') t) (Union.union.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasUnion.{max u1 u2} (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β], Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β (Union.union.{u2} (Finset.{u2} α) (Finset.instUnionFinset.{u2} α (fun (a : α) (b : α) => _inst_1 a b)) s s') t) (Union.union.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instUnionFinset.{max u2 u1} (Prod.{u2, u1} α β) (fun (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β) => instDecidableEqProd.{u2, u1} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t))
-Case conversion may be inaccurate. Consider using '#align finset.union_product Finset.union_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -454,12 +286,6 @@ theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s
   ext ⟨x, y⟩; simp only [or_and_right, mem_union, mem_product]
 #align finset.union_product Finset.union_product
 
-/- warning: finset.product_union -> Finset.product_union is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (Union.union.{u2} (Finset.{u2} β) (Finset.hasUnion.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) t t')) (Union.union.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasUnion.{max u1 u2} (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} {t' : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β], Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s (Union.union.{u1} (Finset.{u1} β) (Finset.instUnionFinset.{u1} β (fun (a : β) (b : β) => _inst_2 a b)) t t')) (Union.union.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instUnionFinset.{max u2 u1} (Prod.{u2, u1} α β) (fun (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β) => instDecidableEqProd.{u2, u1} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s t'))
-Case conversion may be inaccurate. Consider using '#align finset.product_union Finset.product_unionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -468,12 +294,6 @@ theorem product_union [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∪ t') = s
   ext ⟨x, y⟩; simp only [and_or_left, mem_union, mem_product]
 #align finset.product_union Finset.product_union
 
-/- warning: finset.inter_product -> Finset.inter_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β (Inter.inter.{u1} (Finset.{u1} α) (Finset.hasInter.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s s') t) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasInter.{max u1 u2} (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β], Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β (Inter.inter.{u2} (Finset.{u2} α) (Finset.instInterFinset.{u2} α (fun (a : α) (b : α) => _inst_1 a b)) s s') t) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instInterFinset.{max u2 u1} (Prod.{u2, u1} α β) (fun (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β) => instDecidableEqProd.{u2, u1} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t))
-Case conversion may be inaccurate. Consider using '#align finset.inter_product Finset.inter_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -481,12 +301,6 @@ theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ˢ t = s
   ext ⟨x, y⟩; simp only [← and_and_right, mem_inter, mem_product]
 #align finset.inter_product Finset.inter_product
 
-/- warning: finset.product_inter -> Finset.product_inter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (Inter.inter.{u2} (Finset.{u2} β) (Finset.hasInter.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) t t')) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasInter.{max u1 u2} (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} {t' : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β], Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s (Inter.inter.{u1} (Finset.{u1} β) (Finset.instInterFinset.{u1} β (fun (a : β) (b : β) => _inst_2 a b)) t t')) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instInterFinset.{max u2 u1} (Prod.{u2, u1} α β) (fun (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β) => instDecidableEqProd.{u2, u1} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s t'))
-Case conversion may be inaccurate. Consider using '#align finset.product_inter Finset.product_interₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -494,12 +308,6 @@ theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s
   ext ⟨x, y⟩; simp only [← and_and_left, mem_inter, mem_product]
 #align finset.product_inter Finset.product_inter
 
-/- warning: finset.product_inter_product -> Finset.product_inter_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β], Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.hasInter.{max u1 u2} (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t')) (Finset.product.{u1, u2} α β (Inter.inter.{u1} (Finset.{u1} α) (Finset.hasInter.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s s') (Inter.inter.{u2} (Finset.{u2} β) (Finset.hasInter.{u2} β (fun (a : β) (b : β) => _inst_2 a b)) t t'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β} {t' : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α] [_inst_2 : DecidableEq.{succ u1} β], Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Inter.inter.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.instInterFinset.{max u2 u1} (Prod.{u2, u1} α β) (fun (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β) => instDecidableEqProd.{u2, u1} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t')) (Finset.product.{u2, u1} α β (Inter.inter.{u2} (Finset.{u2} α) (Finset.instInterFinset.{u2} α (fun (a : α) (b : α) => _inst_1 a b)) s s') (Inter.inter.{u1} (Finset.{u1} β) (Finset.instInterFinset.{u1} β (fun (a : β) (b : β) => _inst_2 a b)) t t'))
-Case conversion may be inaccurate. Consider using '#align finset.product_inter_product Finset.product_inter_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -508,24 +316,12 @@ theorem product_inter_product [DecidableEq α] [DecidableEq β] :
   simp only [and_assoc', and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
 
-/- warning: finset.disjoint_product -> Finset.disjoint_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β}, Iff (Disjoint.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.partialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.orderBot.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t')) (Or (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s') (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t'))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β}, Iff (Disjoint.{max u2 u1} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.partialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t')) (Or (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} α) s s') (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} β) t t'))
-Case conversion may be inaccurate. Consider using '#align finset.disjoint_product Finset.disjoint_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem disjoint_product : Disjoint (s ×ˢ t) (s' ×ˢ t') ↔ Disjoint s s' ∨ Disjoint t t' := by
   simp_rw [← disjoint_coe, coe_product, Set.disjoint_prod]
 #align finset.disjoint_product Finset.disjoint_product
 
-/- warning: finset.disj_union_product -> Finset.disjUnion_product is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {s' : Finset.{u1} α} {t : Finset.{u2} β} (hs : Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s'), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β (Finset.disjUnion.{u1} α s s' hs) t) (Finset.disjUnion.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t) (Iff.mpr (Disjoint.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.partialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.orderBot.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s' t)) (Or (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s') (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t)) (Finset.disjoint_product.{u1, u2} α β s s' t t) (Or.inl (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s') (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t) hs)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {s' : Finset.{u2} α} {t : Finset.{u1} β} (hs : Disjoint.{u2} (Finset.{u2} α) (Finset.partialOrder.{u2} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} α) s s'), Eq.{max (succ u2) (succ u1)} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β (Finset.disjUnion.{u2} α s s' hs) t) (Finset.disjUnion.{max u2 u1} (Prod.{u2, u1} α β) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t) (Iff.mpr (Disjoint.{max u1 u2} (Finset.{max u1 u2} (Prod.{u2, u1} α β)) (Finset.partialOrder.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{max u2 u1} (Prod.{u2, u1} α β)) (Finset.product.{u2, u1} α β s t) (Finset.product.{u2, u1} α β s' t)) (Or (Disjoint.{u2} (Finset.{u2} α) (Finset.partialOrder.{u2} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} α) s s') (Disjoint.{u1} (Finset.{u1} β) (Finset.partialOrder.{u1} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} β) t t)) (Finset.disjoint_product.{u2, u1} α β s s' t t) (Or.inl (Disjoint.{u2} (Finset.{u2} α) (Finset.partialOrder.{u2} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} α) s s') (Disjoint.{u1} (Finset.{u1} β) (Finset.partialOrder.{u1} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} β) t t) hs)))
-Case conversion may be inaccurate. Consider using '#align finset.disj_union_product Finset.disjUnion_productₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -535,12 +331,6 @@ theorem disjUnion_product (hs : Disjoint s s') :
   eq_of_veq <| Multiset.add_product _ _ _
 #align finset.disj_union_product Finset.disjUnion_product
 
-/- warning: finset.product_disj_union -> Finset.product_disjUnion is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β} (ht : Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t'), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (Finset.disjUnion.{u2} β t t' ht)) (Finset.disjUnion.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t') (Iff.mpr (Disjoint.{max u1 u2} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.partialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.orderBot.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t')) (Or (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s) (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t')) (Finset.disjoint_product.{u1, u2} α β s s t t') (Or.inr (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s s) (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.orderBot.{u2} β) t t') ht)))
-but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} {s : Finset.{u1} α} {t : Finset.{u2} β} {t' : Finset.{u2} β} (ht : Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} β) t t'), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s (Finset.disjUnion.{u2} β t t' ht)) (Finset.disjUnion.{max u1 u2} (Prod.{u1, u2} α β) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t') (Iff.mpr (Disjoint.{max u2 u1} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.partialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.product.{u1, u2} α β s t')) (Or (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} α) s s) (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} β) t t')) (Finset.disjoint_product.{u1, u2} α β s s t t') (Or.inr (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} α) s s) (Disjoint.{u2} (Finset.{u2} β) (Finset.partialOrder.{u2} β) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u2} β) t t') ht)))
-Case conversion may be inaccurate. Consider using '#align finset.product_disj_union Finset.product_disjUnionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
@@ -654,90 +444,42 @@ theorem offDiag_empty : (∅ : Finset α).offDiag = ∅ :=
 #align finset.off_diag_empty Finset.offDiag_empty
 -/
 
-/- warning: finset.diag_union_off_diag -> Finset.diag_union_offDiag is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.product.{u1, u1} α α s s)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.product.{u1, u1} α α s s)
-Case conversion may be inaccurate. Consider using '#align finset.diag_union_off_diag Finset.diag_union_offDiagₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem diag_union_offDiag : s.diag ∪ s.offDiag = s ×ˢ s :=
   filter_union_filter_neg_eq _ _
 #align finset.diag_union_off_diag Finset.diag_union_offDiag
 
-/- warning: finset.disjoint_diag_off_diag -> Finset.disjoint_diag_offDiag is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Disjoint.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.partialOrder.{u1} (Prod.{u1, u1} α α)) (Finset.orderBot.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Disjoint.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.partialOrder.{u1} (Prod.{u1, u1} α α)) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-Case conversion may be inaccurate. Consider using '#align finset.disjoint_diag_off_diag Finset.disjoint_diag_offDiagₓ'. -/
 @[simp]
 theorem disjoint_diag_offDiag : Disjoint s.diag s.offDiag :=
   disjoint_filter_filter_neg _ _ _
 #align finset.disjoint_diag_off_diag Finset.disjoint_diag_offDiag
 
-/- warning: finset.product_sdiff_diag -> Finset.product_sdiff_diag is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (SDiff.sdiff.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasSdiff.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.product.{u1, u1} α α s s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (SDiff.sdiff.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instSDiffFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.product.{u1, u1} α α s s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-Case conversion may be inaccurate. Consider using '#align finset.product_sdiff_diag Finset.product_sdiff_diagₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_sdiff_diag : s ×ˢ s \ s.diag = s.offDiag := by
   rw [← diag_union_off_diag, union_comm, union_sdiff_self,
     sdiff_eq_self_of_disjoint (disjoint_diag_off_diag _).symm]
 #align finset.product_sdiff_diag Finset.product_sdiff_diag
 
-/- warning: finset.product_sdiff_off_diag -> Finset.product_sdiff_offDiag is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (SDiff.sdiff.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasSdiff.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.product.{u1, u1} α α s s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (SDiff.sdiff.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instSDiffFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.product.{u1, u1} α α s s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s)
-Case conversion may be inaccurate. Consider using '#align finset.product_sdiff_off_diag Finset.product_sdiff_offDiagₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_sdiff_offDiag : s ×ˢ s \ s.offDiag = s.diag := by
   rw [← diag_union_off_diag, union_sdiff_self, sdiff_eq_self_of_disjoint (disjoint_diag_off_diag _)]
 #align finset.product_sdiff_off_diag Finset.product_sdiff_offDiag
 
-/- warning: finset.diag_inter -> Finset.diag_inter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Inter.inter.{u1} (Finset.{u1} α) (Finset.hasInter.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Inter.inter.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasInter.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Inter.inter.{u1} (Finset.{u1} α) (Finset.instInterFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Inter.inter.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instInterFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-Case conversion may be inaccurate. Consider using '#align finset.diag_inter Finset.diag_interₓ'. -/
 theorem diag_inter : (s ∩ t).diag = s.diag ∩ t.diag :=
   ext fun x => by simpa only [mem_diag, mem_inter] using and_and_right _ _ _
 #align finset.diag_inter Finset.diag_inter
 
-/- warning: finset.off_diag_inter -> Finset.offDiag_inter is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Inter.inter.{u1} (Finset.{u1} α) (Finset.hasInter.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Inter.inter.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasInter.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Inter.inter.{u1} (Finset.{u1} α) (Finset.instInterFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Inter.inter.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instInterFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-Case conversion may be inaccurate. Consider using '#align finset.off_diag_inter Finset.offDiag_interₓ'. -/
 theorem offDiag_inter : (s ∩ t).offDiag = s.offDiag ∩ t.offDiag :=
   coe_injective <| by push_cast ; exact Set.offDiag_inter _ _
 #align finset.off_diag_inter Finset.offDiag_inter
 
-/- warning: finset.diag_union -> Finset.diag_union is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
-Case conversion may be inaccurate. Consider using '#align finset.diag_union Finset.diag_unionₓ'. -/
 theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag := by ext ⟨i, j⟩;
   simp only [mem_diag, mem_union, or_and_right]
 #align finset.diag_union Finset.diag_union
 
 variable {s t}
 
-/- warning: finset.off_diag_union -> Finset.offDiag_union is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} {t : Finset.{u1} α}, (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.orderBot.{u1} α) s t) -> (Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Union.union.{u1} (Finset.{u1} α) (Finset.hasUnion.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t)) (Finset.product.{u1, u1} α α s t)) (Finset.product.{u1, u1} α α t s)))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} {t : Finset.{u1} α}, (Disjoint.{u1} (Finset.{u1} α) (Finset.partialOrder.{u1} α) (Finset.instOrderBotFinsetToLEToPreorderPartialOrder.{u1} α) s t) -> (Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t)) (Finset.product.{u1, u1} α α s t)) (Finset.product.{u1, u1} α α t s)))
-Case conversion may be inaccurate. Consider using '#align finset.off_diag_union Finset.offDiag_unionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem offDiag_union (h : Disjoint s t) :
@@ -759,22 +501,10 @@ theorem diag_singleton : ({a} : Finset α).diag = {(a, a)} := by
 #align finset.diag_singleton Finset.diag_singleton
 -/
 
-/- warning: finset.diag_insert -> Finset.diag_insert is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} (a : α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Insert.insert.{u1, u1} α (Finset.{u1} α) (Finset.hasInsert.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a s)) (Insert.insert.{u1, u1} (Prod.{u1, u1} α α) (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasInsert.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Prod.mk.{u1, u1} α α a a) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} (a : α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Insert.insert.{u1, u1} α (Finset.{u1} α) (Finset.instInsertFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a s)) (Insert.insert.{u1, u1} (Prod.{u1, u1} α α) (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instInsertFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Prod.mk.{u1, u1} α α a a) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s))
-Case conversion may be inaccurate. Consider using '#align finset.diag_insert Finset.diag_insertₓ'. -/
 theorem diag_insert : (insert a s).diag = insert (a, a) s.diag := by
   rw [insert_eq, insert_eq, diag_union, diag_singleton]
 #align finset.diag_insert Finset.diag_insert
 
-/- warning: finset.off_diag_insert -> Finset.offDiag_insert is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} (a : α), (Not (Membership.Mem.{u1, u1} α (Finset.{u1} α) (Finset.hasMem.{u1} α) a s)) -> (Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Insert.insert.{u1, u1} α (Finset.{u1} α) (Finset.hasInsert.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a s)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.hasUnion.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => Prod.decidableEq.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.product.{u1, u1} α α (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.hasSingleton.{u1} α) a) s)) (Finset.product.{u1, u1} α α s (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.hasSingleton.{u1} α) a))))
-but is expected to have type
-  forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] {s : Finset.{u1} α} (a : α), (Not (Membership.mem.{u1, u1} α (Finset.{u1} α) (Finset.instMembershipFinset.{u1} α) a s)) -> (Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Insert.insert.{u1, u1} α (Finset.{u1} α) (Finset.instInsertFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) a s)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.product.{u1, u1} α α (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.instSingletonFinset.{u1} α) a) s)) (Finset.product.{u1, u1} α α s (Singleton.singleton.{u1, u1} α (Finset.{u1} α) (Finset.instSingletonFinset.{u1} α) a))))
-Case conversion may be inaccurate. Consider using '#align finset.off_diag_insert Finset.offDiag_insertₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem offDiag_insert (has : a ∉ s) : (insert a s).offDiag = s.offDiag ∪ {a} ×ˢ s ∪ s ×ˢ {a} := by
Diff
@@ -128,18 +128,14 @@ but is expected to have type
   forall {α : Type.{u2}} {β : Type.{u1}} {s : Finset.{u2} α} {t : Finset.{u1} β} [_inst_1 : DecidableEq.{succ u2} α], (Finset.Nonempty.{u1} β t) -> (Eq.{succ u2} (Finset.{u2} α) (Finset.image.{max u1 u2, u2} (Prod.{u2, u1} α β) α (fun (a : α) (b : α) => _inst_1 a b) (Prod.fst.{u2, u1} α β) (Finset.product.{u2, u1} α β s t)) s)
 Case conversion may be inaccurate. Consider using '#align finset.product_image_fst Finset.product_image_fstₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
-theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s :=
-  by
-  ext i
-  simp [mem_image, ht.bex]
+theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s := by
+  ext i; simp [mem_image, ht.bex]
 #align finset.product_image_fst Finset.product_image_fst
 
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 #print Finset.product_image_snd /-
-theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image Prod.snd = t :=
-  by
-  ext i
-  simp [mem_image, ht.bex]
+theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image Prod.snd = t := by
+  ext i; simp [mem_image, ht.bex]
 #align finset.product_image_snd Finset.product_image_snd
 -/
 
@@ -197,9 +193,7 @@ Case conversion may be inaccurate. Consider using '#align finset.map_swap_produc
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem map_swap_product (s : Finset α) (t : Finset β) :
     (t ×ˢ s).map ⟨Prod.swap, Prod.swap_injective⟩ = s ×ˢ t :=
-  coe_injective <| by
-    push_cast
-    exact Set.image_swap_prod _ _
+  coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.map_swap_product Finset.map_swap_product
 
 /- warning: finset.image_swap_product -> Finset.image_swap_product is a dubious translation:
@@ -213,9 +207,7 @@ Case conversion may be inaccurate. Consider using '#align finset.image_swap_prod
 @[simp]
 theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
     (t ×ˢ s).image Prod.swap = s ×ˢ t :=
-  coe_injective <| by
-    push_cast
-    exact Set.image_swap_prod _ _
+  coe_injective <| by push_cast ; exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
 /- warning: finset.product_eq_bUnion -> Finset.product_eq_biUnion is a dubious translation:
@@ -283,8 +275,7 @@ Case conversion may be inaccurate. Consider using '#align finset.filter_product
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
     ((s ×ˢ t).filterₓ fun x : α × β => p x.1 ∧ q x.2) = s.filterₓ p ×ˢ t.filterₓ q :=
   by
-  ext ⟨a, b⟩
-  simp only [mem_filter, mem_product]
+  ext ⟨a, b⟩; simp only [mem_filter, mem_product]
   exact and_and_and_comm (a ∈ s) (b ∈ t) (p a) (q b)
 #align finset.filter_product Finset.filter_product
 
@@ -325,14 +316,10 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
   by
   classical
     rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
-    · apply congr_arg
-      ext ⟨a, b⟩
-      simp only [filter_union_right, mem_filter, mem_product]
+    · apply congr_arg; ext ⟨a, b⟩; simp only [filter_union_right, mem_filter, mem_product]
       constructor <;> intro h <;> use h.1
       simp only [Function.comp_apply, and_self_iff, h.2, em (q b)]
-      cases h.2 <;>
-        · try simp at h_1
-          simp [h_1]
+      cases h.2 <;> · try simp at h_1; simp [h_1]
     · apply Finset.disjoint_filter_filter'
       exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
@@ -426,9 +413,7 @@ Case conversion may be inaccurate. Consider using '#align finset.singleton_produ
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
 theorem singleton_product {a : α} : ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ :=
-  by
-  ext ⟨x, y⟩
-  simp [and_left_comm, eq_comm]
+  by ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.singleton_product Finset.singleton_product
 
 /- warning: finset.product_singleton -> Finset.product_singleton is a dubious translation:
@@ -439,10 +424,8 @@ but is expected to have type
 Case conversion may be inaccurate. Consider using '#align finset.product_singleton Finset.product_singletonₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
-theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ :=
-  by
-  ext ⟨x, y⟩
-  simp [and_left_comm, eq_comm]
+theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
+  ext ⟨x, y⟩; simp [and_left_comm, eq_comm]
 #align finset.product_singleton Finset.product_singleton
 
 /- warning: finset.singleton_product_singleton -> Finset.singleton_product_singleton is a dubious translation:
@@ -467,10 +450,8 @@ Case conversion may be inaccurate. Consider using '#align finset.union_product F
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
-theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s ×ˢ t ∪ s' ×ˢ t :=
-  by
-  ext ⟨x, y⟩
-  simp only [or_and_right, mem_union, mem_product]
+theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s ×ˢ t ∪ s' ×ˢ t := by
+  ext ⟨x, y⟩; simp only [or_and_right, mem_union, mem_product]
 #align finset.union_product Finset.union_product
 
 /- warning: finset.product_union -> Finset.product_union is a dubious translation:
@@ -483,10 +464,8 @@ Case conversion may be inaccurate. Consider using '#align finset.product_union F
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 @[simp]
-theorem product_union [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∪ t') = s ×ˢ t ∪ s ×ˢ t' :=
-  by
-  ext ⟨x, y⟩
-  simp only [and_or_left, mem_union, mem_product]
+theorem product_union [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∪ t') = s ×ˢ t ∪ s ×ˢ t' := by
+  ext ⟨x, y⟩; simp only [and_or_left, mem_union, mem_product]
 #align finset.product_union Finset.product_union
 
 /- warning: finset.inter_product -> Finset.inter_product is a dubious translation:
@@ -498,10 +477,8 @@ Case conversion may be inaccurate. Consider using '#align finset.inter_product F
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
-theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ˢ t = s ×ˢ t ∩ s' ×ˢ t :=
-  by
-  ext ⟨x, y⟩
-  simp only [← and_and_right, mem_inter, mem_product]
+theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ˢ t = s ×ˢ t ∩ s' ×ˢ t := by
+  ext ⟨x, y⟩; simp only [← and_and_right, mem_inter, mem_product]
 #align finset.inter_product Finset.inter_product
 
 /- warning: finset.product_inter -> Finset.product_inter is a dubious translation:
@@ -513,10 +490,8 @@ Case conversion may be inaccurate. Consider using '#align finset.product_inter F
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
-theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s ×ˢ t ∩ s ×ˢ t' :=
-  by
-  ext ⟨x, y⟩
-  simp only [← and_and_left, mem_inter, mem_product]
+theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s ×ˢ t ∩ s ×ˢ t' := by
+  ext ⟨x, y⟩; simp only [← and_and_left, mem_inter, mem_product]
 #align finset.product_inter Finset.product_inter
 
 /- warning: finset.product_inter_product -> Finset.product_inter_product is a dubious translation:
@@ -529,9 +504,7 @@ Case conversion may be inaccurate. Consider using '#align finset.product_inter_p
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem product_inter_product [DecidableEq α] [DecidableEq β] :
-    s ×ˢ t ∩ s' ×ˢ t' = (s ∩ s') ×ˢ (t ∩ t') :=
-  by
-  ext ⟨x, y⟩
+    s ×ˢ t ∩ s' ×ˢ t' = (s ∩ s') ×ˢ (t ∩ t') := by ext ⟨x, y⟩;
   simp only [and_assoc', and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
 
@@ -607,18 +580,16 @@ variable {s} {x : α × α}
 @[simp]
 theorem mem_diag : x ∈ s.diag ↔ x.1 ∈ s ∧ x.1 = x.2 :=
   by
-  simp only [diag, mem_filter, mem_product]
+  simp only [diag, mem_filter, mem_product];
   constructor <;> intro h <;> simp only [h, and_true_iff, eq_self_iff_true, and_self_iff]
-  rw [← h.2]
-  exact h.1
+  rw [← h.2]; exact h.1
 #align finset.mem_diag Finset.mem_diag
 -/
 
 #print Finset.mem_offDiag /-
 @[simp]
-theorem mem_offDiag : x ∈ s.offDiag ↔ x.1 ∈ s ∧ x.2 ∈ s ∧ x.1 ≠ x.2 :=
-  by
-  simp only [off_diag, mem_filter, mem_product]
+theorem mem_offDiag : x ∈ s.offDiag ↔ x.1 ∈ s ∧ x.2 ∈ s ∧ x.1 ≠ x.2 := by
+  simp only [off_diag, mem_filter, mem_product];
   constructor <;> intro h <;> simp only [h, Ne.def, not_false_iff, and_self_iff]
 #align finset.mem_off_diag Finset.mem_offDiag
 -/
@@ -636,18 +607,11 @@ theorem coe_offDiag : (s.offDiag : Set (α × α)) = (s : Set α).offDiag :=
 @[simp]
 theorem diag_card : (diag s).card = s.card :=
   by
-  suffices diag s = s.image fun a => (a, a) by
-    rw [this]
-    apply card_image_of_inj_on
+  suffices diag s = s.image fun a => (a, a) by rw [this]; apply card_image_of_inj_on;
     exact fun x1 h1 x2 h2 h3 => (Prod.mk.inj h3).1
-  ext ⟨a₁, a₂⟩
-  rw [mem_diag]
-  constructor <;> intro h <;> rw [Finset.mem_image] at *
+  ext ⟨a₁, a₂⟩; rw [mem_diag]; constructor <;> intro h <;> rw [Finset.mem_image] at *
   · use a₁, h.1, prod.mk.inj_iff.mpr ⟨rfl, h.2⟩
-  · rcases h with ⟨a, h1, h2⟩
-    have h := Prod.mk.inj h2
-    rw [← h.1, ← h.2]
-    use h1
+  · rcases h with ⟨a, h1, h2⟩; have h := Prod.mk.inj h2; rw [← h.1, ← h.2]; use h1
 #align finset.diag_card Finset.diag_card
 -/
 
@@ -655,12 +619,8 @@ theorem diag_card : (diag s).card = s.card :=
 @[simp]
 theorem offDiag_card : (offDiag s).card = s.card * s.card - s.card :=
   by
-  suffices (diag s).card + (off_diag s).card = s.card * s.card
-    by
-    nth_rw 3 [← s.diag_card]
-    simp only [diag_card] at *
-    rw [tsub_eq_of_eq_add_rev]
-    rw [this]
+  suffices (diag s).card + (off_diag s).card = s.card * s.card by nth_rw 3 [← s.diag_card];
+    simp only [diag_card] at *; rw [tsub_eq_of_eq_add_rev]; rw [this]
   rw [← card_product]
   apply filter_card_add_filter_neg_card_eq_card
 #align finset.off_diag_card Finset.offDiag_card
@@ -757,9 +717,7 @@ but is expected to have type
   forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Inter.inter.{u1} (Finset.{u1} α) (Finset.instInterFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Inter.inter.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instInterFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.offDiag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
 Case conversion may be inaccurate. Consider using '#align finset.off_diag_inter Finset.offDiag_interₓ'. -/
 theorem offDiag_inter : (s ∩ t).offDiag = s.offDiag ∩ t.offDiag :=
-  coe_injective <| by
-    push_cast
-    exact Set.offDiag_inter _ _
+  coe_injective <| by push_cast ; exact Set.offDiag_inter _ _
 #align finset.off_diag_inter Finset.offDiag_inter
 
 /- warning: finset.diag_union -> Finset.diag_union is a dubious translation:
@@ -768,9 +726,7 @@ lean 3 declaration is
 but is expected to have type
   forall {α : Type.{u1}} [_inst_1 : DecidableEq.{succ u1} α] (s : Finset.{u1} α) (t : Finset.{u1} α), Eq.{succ u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) (Union.union.{u1} (Finset.{u1} α) (Finset.instUnionFinset.{u1} α (fun (a : α) (b : α) => _inst_1 a b)) s t)) (Union.union.{u1} (Finset.{u1} (Prod.{u1, u1} α α)) (Finset.instUnionFinset.{u1} (Prod.{u1, u1} α α) (fun (a : Prod.{u1, u1} α α) (b : Prod.{u1, u1} α α) => instDecidableEqProd.{u1, u1} α α (fun (a : α) (b : α) => _inst_1 a b) (fun (a : α) (b : α) => _inst_1 a b) a b)) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) s) (Finset.diag.{u1} α (fun (a : α) (b : α) => _inst_1 a b) t))
 Case conversion may be inaccurate. Consider using '#align finset.diag_union Finset.diag_unionₓ'. -/
-theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag :=
-  by
-  ext ⟨i, j⟩
+theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag := by ext ⟨i, j⟩;
   simp only [mem_diag, mem_union, or_and_right]
 #align finset.diag_union Finset.diag_union
 
@@ -786,9 +742,7 @@ Case conversion may be inaccurate. Consider using '#align finset.off_diag_union
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem offDiag_union (h : Disjoint s t) :
     (s ∪ t).offDiag = s.offDiag ∪ t.offDiag ∪ s ×ˢ t ∪ t ×ˢ s :=
-  coe_injective <| by
-    push_cast
-    exact Set.offDiag_union (disjoint_coe.2 h)
+  coe_injective <| by push_cast ; exact Set.offDiag_union (disjoint_coe.2 h)
 #align finset.off_diag_union Finset.offDiag_union
 
 variable (a : α)
Diff
@@ -218,47 +218,47 @@ theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t
     exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
-/- warning: finset.product_eq_bUnion -> Finset.product_eq_bunionᵢ is a dubious translation:
+/- warning: finset.product_eq_bUnion -> Finset.product_eq_biUnion is a dubious translation:
 lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.bunionᵢ.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) s (fun (a : α) => Finset.image.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) t))
+  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.biUnion.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) s (fun (a : α) => Finset.image.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) t))
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.bunionᵢ.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) _inst_2 (fun (a : α) => Finset.image.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) s))
-Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion Finset.product_eq_bunionᵢₓ'. -/
+  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.biUnion.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) _inst_2 (fun (a : α) => Finset.image.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (b : β) => Prod.mk.{u1, u2} α β a b) s))
+Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion Finset.product_eq_biUnionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
-theorem product_eq_bunionᵢ [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
-    s ×ˢ t = s.bunionᵢ fun a => t.image fun b => (a, b) :=
+theorem product_eq_biUnion [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
+    s ×ˢ t = s.biUnion fun a => t.image fun b => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
-#align finset.product_eq_bUnion Finset.product_eq_bunionᵢ
+#align finset.product_eq_bUnion Finset.product_eq_biUnion
 
-/- warning: finset.product_eq_bUnion_right -> Finset.product_eq_bunionᵢ_right is a dubious translation:
+/- warning: finset.product_eq_bUnion_right -> Finset.product_eq_biUnion_right is a dubious translation:
 lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.bunionᵢ.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) t (fun (b : β) => Finset.image.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) s))
+  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{succ u1} α] [_inst_2 : DecidableEq.{succ u2} β] (s : Finset.{u1} α) (t : Finset.{u2} β), Eq.{succ (max u1 u2)} (Finset.{max u1 u2} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β s t) (Finset.biUnion.{u2, max u1 u2} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) t (fun (b : β) => Finset.image.{u1, max u1 u2} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => Prod.decidableEq.{u1, u2} α β (fun (a : α) (b : α) => _inst_1 a b) (fun (a : β) (b : β) => _inst_2 a b) a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) s))
 but is expected to have type
-  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.bunionᵢ.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) s (fun (b : β) => Finset.image.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) _inst_2))
-Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion_right Finset.product_eq_bunionᵢ_rightₓ'. -/
+  forall {α : Type.{u1}} {β : Type.{u2}} [_inst_1 : DecidableEq.{max (succ u2) (succ u1)} (Prod.{u1, u2} α β)] (_inst_2 : Finset.{u1} α) (s : Finset.{u2} β), Eq.{max (succ u1) (succ u2)} (Finset.{max u2 u1} (Prod.{u1, u2} α β)) (Finset.product.{u1, u2} α β _inst_2 s) (Finset.biUnion.{u2, max u2 u1} β (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) s (fun (b : β) => Finset.image.{u1, max u2 u1} α (Prod.{u1, u2} α β) (fun (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β) => _inst_1 a b) (fun (a : α) => Prod.mk.{u1, u2} α β a b) _inst_2))
+Case conversion may be inaccurate. Consider using '#align finset.product_eq_bUnion_right Finset.product_eq_biUnion_rightₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
-theorem product_eq_bunionᵢ_right [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
-    s ×ˢ t = t.bunionᵢ fun b => s.image fun a => (a, b) :=
+theorem product_eq_biUnion_right [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
+    s ×ˢ t = t.biUnion fun b => s.image fun a => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
-#align finset.product_eq_bUnion_right Finset.product_eq_bunionᵢ_right
+#align finset.product_eq_bUnion_right Finset.product_eq_biUnion_right
 
-/- warning: finset.product_bUnion -> Finset.product_bunionᵢ is a dubious translation:
+/- warning: finset.product_bUnion -> Finset.product_biUnion is a dubious translation:
 lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u1} α) (t : Finset.{u2} β) (f : (Prod.{u1, u2} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.bunionᵢ.{max u1 u2, u3} (Prod.{u1, u2} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u1, u2} α β s t) f) (Finset.bunionᵢ.{u1, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.bunionᵢ.{u2, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u1, u2} α β a b))))
+  forall {α : Type.{u1}} {β : Type.{u2}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u1} α) (t : Finset.{u2} β) (f : (Prod.{u1, u2} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.biUnion.{max u1 u2, u3} (Prod.{u1, u2} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u1, u2} α β s t) f) (Finset.biUnion.{u1, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.biUnion.{u2, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u1, u2} α β a b))))
 but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u2} α) (t : Finset.{u1} β) (f : (Prod.{u2, u1} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.bunionᵢ.{max u2 u1, u3} (Prod.{u2, u1} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u2, u1} α β s t) f) (Finset.bunionᵢ.{u2, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.bunionᵢ.{u1, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u2, u1} α β a b))))
-Case conversion may be inaccurate. Consider using '#align finset.product_bUnion Finset.product_bunionᵢₓ'. -/
+  forall {α : Type.{u2}} {β : Type.{u1}} {γ : Type.{u3}} [_inst_1 : DecidableEq.{succ u3} γ] (s : Finset.{u2} α) (t : Finset.{u1} β) (f : (Prod.{u2, u1} α β) -> (Finset.{u3} γ)), Eq.{succ u3} (Finset.{u3} γ) (Finset.biUnion.{max u2 u1, u3} (Prod.{u2, u1} α β) γ (fun (a : γ) (b : γ) => _inst_1 a b) (Finset.product.{u2, u1} α β s t) f) (Finset.biUnion.{u2, u3} α γ (fun (a : γ) (b : γ) => _inst_1 a b) s (fun (a : α) => Finset.biUnion.{u1, u3} β γ (fun (a : γ) (b : γ) => _inst_1 a b) t (fun (b : β) => f (Prod.mk.{u2, u1} α β a b))))
+Case conversion may be inaccurate. Consider using '#align finset.product_bUnion Finset.product_biUnionₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 /-- See also `finset.sup_product_left`. -/
 @[simp]
-theorem product_bunionᵢ [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
-    (s ×ˢ t).bunionᵢ f = s.bunionᵢ fun a => t.bunionᵢ fun b => f (a, b) := by
+theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
+    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
   classical simp_rw [product_eq_bUnion, bUnion_bUnion, image_bUnion]
-#align finset.product_bUnion Finset.product_bunionᵢ
+#align finset.product_bUnion Finset.product_biUnion
 
 /- warning: finset.card_product -> Finset.card_product is a dubious translation:
 lean 3 declaration is
Diff
@@ -314,7 +314,7 @@ theorem filter_product_right (q : β → Prop) [DecidablePred q] :
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} (s : Finset.{u1} α) (t : Finset.{u2} β) (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u1} α p] [_inst_2 : DecidablePred.{succ u2} β q], Eq.{1} Nat (Finset.card.{max u1 u2} (Prod.{u1, u2} α β) (Finset.filter.{max u1 u2} (Prod.{u1, u2} α β) (fun (x : Prod.{u1, u2} α β) => Iff (p (Prod.fst.{u1, u2} α β x)) (q (Prod.snd.{u1, u2} α β x))) (fun (a : Prod.{u1, u2} α β) => Iff.decidable (p (Prod.fst.{u1, u2} α β a)) (q (Prod.snd.{u1, u2} α β a)) (_inst_1 (Prod.fst.{u1, u2} α β a)) (_inst_2 (Prod.snd.{u1, u2} α β a))) (Finset.product.{u1, u2} α β s t))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (Finset.filter.{u1} α p (fun (a : α) => _inst_1 a) s)) (Finset.card.{u2} β (Finset.filter.{u2} β q (fun (a : β) => _inst_2 a) t))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Finset.card.{u1} α (Finset.filter.{u1} α (Function.comp.{succ u1, 1, 1} α Prop Prop Not p) (fun (a : α) => Not.decidable (p a) (_inst_1 a)) s)) (Finset.card.{u2} β (Finset.filter.{u2} β (Function.comp.{succ u2, 1, 1} β Prop Prop Not q) (fun (a : β) => Not.decidable (q a) (_inst_2 a)) t))))
 but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β) (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u2} α p] [_inst_2 : DecidablePred.{succ u1} β q], Eq.{1} Nat (Finset.card.{max u2 u1} (Prod.{u2, u1} α β) (Finset.filter.{max u2 u1} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => Eq.{1} Prop (p (Prod.fst.{u2, u1} α β x)) (q (Prod.snd.{u2, u1} α β x))) (fun (a : Prod.{u2, u1} α β) => instDecidableEqProp (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (instDecidableIff (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (_inst_1 (Prod.fst.{u2, u1} α β a)) (_inst_2 (Prod.snd.{u2, u1} α β a)))) (Finset.product.{u2, u1} α β s t))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α p (fun (a : α) => _inst_1 a) s)) (Finset.card.{u1} β (Finset.filter.{u1} β q (fun (a : β) => _inst_2 a) t))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1940 : α) => Not (p x._@.Mathlib.Data.Finset.Prod._hyg.1940)) (fun (a : α) => instDecidableNot (p a) (_inst_1 a)) s)) (Finset.card.{u1} β (Finset.filter.{u1} β (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1956 : β) => Not (q x._@.Mathlib.Data.Finset.Prod._hyg.1956)) (fun (a : β) => instDecidableNot (q a) (_inst_2 a)) t))))
+  forall {α : Type.{u2}} {β : Type.{u1}} (s : Finset.{u2} α) (t : Finset.{u1} β) (p : α -> Prop) (q : β -> Prop) [_inst_1 : DecidablePred.{succ u2} α p] [_inst_2 : DecidablePred.{succ u1} β q], Eq.{1} Nat (Finset.card.{max u2 u1} (Prod.{u2, u1} α β) (Finset.filter.{max u2 u1} (Prod.{u2, u1} α β) (fun (x : Prod.{u2, u1} α β) => Eq.{1} Prop (p (Prod.fst.{u2, u1} α β x)) (q (Prod.snd.{u2, u1} α β x))) (fun (a : Prod.{u2, u1} α β) => instDecidableEqProp (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (instDecidableIff (p (Prod.fst.{u2, u1} α β a)) (q (Prod.snd.{u2, u1} α β a)) (_inst_1 (Prod.fst.{u2, u1} α β a)) (_inst_2 (Prod.snd.{u2, u1} α β a)))) (Finset.product.{u2, u1} α β s t))) (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α p (fun (a : α) => _inst_1 a) s)) (Finset.card.{u1} β (Finset.filter.{u1} β q (fun (a : β) => _inst_2 a) t))) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Finset.card.{u2} α (Finset.filter.{u2} α (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1938 : α) => Not (p x._@.Mathlib.Data.Finset.Prod._hyg.1938)) (fun (a : α) => instDecidableNot (p a) (_inst_1 a)) s)) (Finset.card.{u1} β (Finset.filter.{u1} β (fun (x._@.Mathlib.Data.Finset.Prod._hyg.1954 : β) => Not (q x._@.Mathlib.Data.Finset.Prod._hyg.1954)) (fun (a : β) => instDecidableNot (q a) (_inst_2 a)) t))))
 Case conversion may be inaccurate. Consider using '#align finset.filter_product_card Finset.filter_product_cardₓ'. -/
 /- ./././Mathport/Syntax/Translate/Expr.lean:177:8: unsupported: ambiguous notation -/
 theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q : β → Prop)

Changes in mathlib4

mathlib3
mathlib4
chore: remove more bex and ball from lemma names (#11615)

Follow-up to #10816.

Remaining places containing such lemmas are

  • Option.bex_ne_none and Option.ball_ne_none: defined in Lean core
  • Nat.decidableBallLT and Nat.decidableBallLE: defined in Lean core
  • bef_def is still used in a number of places and could be renamed
  • BAll.imp_{left,right}, BEx.imp_{left,right}, BEx.intro and BEx.elim

I only audited the first ~150 lemmas mentioning "ball"; too many lemmas named after Metric.ball/openBall/closedBall.

Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>

Diff
@@ -74,12 +74,12 @@ theorem subset_product_image_snd [DecidableEq β] : (s ×ˢ t).image Prod.snd 
 
 theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s := by
   ext i
-  simp [mem_image, ht.bex]
+  simp [mem_image, ht.exists_mem]
 #align finset.product_image_fst Finset.product_image_fst
 
 theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image Prod.snd = t := by
   ext i
-  simp [mem_image, ht.bex]
+  simp [mem_image, ht.exists_mem]
 #align finset.product_image_snd Finset.product_image_snd
 
 theorem subset_product [DecidableEq α] [DecidableEq β] {s : Finset (α × β)} :
chore: bump aesop; update syntax (#10955)

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

Diff
@@ -205,7 +205,7 @@ theorem Nonempty.snd (h : (s ×ˢ t).Nonempty) : t.Nonempty :=
   ⟨xy.2, (mem_product.1 hxy).2⟩
 #align finset.nonempty.snd Finset.Nonempty.snd
 
-@[simp, aesop safe apply (rule_sets [finsetNonempty])]
+@[simp, aesop safe apply (rule_sets := [finsetNonempty])]
 theorem nonempty_product : (s ×ˢ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
   ⟨fun h => ⟨h.fst, h.snd⟩, fun h => h.1.product h.2⟩
 #align finset.nonempty_product Finset.nonempty_product
feat: Positivity extension for Finset.sum (#10538)

Also define a new aesop rule-set and an auxiliary metaprogram proveFinsetNonempty for dealing with Finset.Nonempty conditions.

From LeanAPAP

Co-authored-by: Alex J. Best <alex.j.best@gmail.com>

Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Alex J Best <alex.j.best@gmail.com>

Diff
@@ -205,7 +205,7 @@ theorem Nonempty.snd (h : (s ×ˢ t).Nonempty) : t.Nonempty :=
   ⟨xy.2, (mem_product.1 hxy).2⟩
 #align finset.nonempty.snd Finset.Nonempty.snd
 
-@[simp]
+@[simp, aesop safe apply (rule_sets [finsetNonempty])]
 theorem nonempty_product : (s ×ˢ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
   ⟨fun h => ⟨h.fst, h.snd⟩, fun h => h.1.product h.2⟩
 #align finset.nonempty_product Finset.nonempty_product
feat: (s ∩ t).card = s.card + t.card - (s ∪ t).card (#10224)

once coerced to an AddGroupWithOne. Also unify Finset.card_disjoint_union and Finset.card_union_eq

From LeanAPAP

Diff
@@ -168,17 +168,17 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
       (s.filter p).card * (t.filter q).card +
         (s.filter (¬ p ·)).card * (t.filter (¬ q ·)).card := by
   classical
-    rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
-    · apply congr_arg
-      ext ⟨a, b⟩
-      simp only [filter_union_right, mem_filter, mem_product]
-      constructor <;> intro h <;> use h.1
-      · simp only [h.2, Function.comp_apply, Decidable.em, and_self]
-      · revert h
-        simp only [Function.comp_apply, and_imp]
-        rintro _ _ (_|_) <;> simp [*]
-    · apply Finset.disjoint_filter_filter'
-      exact (disjoint_compl_right.inf_left _).inf_right _
+  rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_of_disjoint]
+  · apply congr_arg
+    ext ⟨a, b⟩
+    simp only [filter_union_right, mem_filter, mem_product]
+    constructor <;> intro h <;> use h.1
+    · simp only [h.2, Function.comp_apply, Decidable.em, and_self]
+    · revert h
+      simp only [Function.comp_apply, and_imp]
+      rintro _ _ (_|_) <;> simp [*]
+  · apply Finset.disjoint_filter_filter'
+    exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
 
 theorem empty_product (t : Finset β) : (∅ : Finset α) ×ˢ t = ∅ :=
feat: tensor algebra of free module over integral domain is a domain (#9890)

Provide instances

  • Nontrivial (TensorAlgebra R M) when M is a module over a nontrivial semiring R
  • NoZeroDivisors (FreeAlgebra R X) when R is a commutative semiring with no zero-divisors and X any type
  • IsDomain (FreeAlgebra R X) when R is an integral domain and X is any type
  • TwoUniqueProds (FreeMonoid X) where X is any type (this provides NoZeroDivisors (MonoidAlgebra R (FreeMonoid X)) when R is a semiring and X any type, via TwoUniqueProds.toUniqueProds and MonoidAlgebra.instNoZeroDivisorsOfUniqueProds)
  • NoZeroDivisors (TensorAlgebra R M) when M is a free module over a commutative semiring R with no zero-divisors
  • IsDomain (TensorAlgebra R M) when M is a free module over an integral domain R

In Algebra.Group.UniqueProds:

  • Rename UniqueProds.mulHom_image_of_injective to UniqueProds.of_injective_mulHom.
  • New lemmas UniqueMul.of_mulHom_image, UniqueProds.of_mulHom, TwoUniqueProds.of_mulHom show the relevant property holds in the domain of a multiplicative homomorphism if it holds in the codomain, under a certain hypothesis on the homomorphism.

Co-authored-by: Richard Copley <rcopley@gmail.com> Co-authored-by: Eric Wieser <wieser.eric@gmail.com> Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>

Diff
@@ -142,9 +142,9 @@ theorem card_product (s : Finset α) (t : Finset β) : card (s ×ˢ t) = card s
 
 /-- The product of two Finsets is nontrivial iff both are nonempty
   at least one of them is nontrivial. -/
-lemma nontrivial_prod_iff : Nontrivial (s ×ˢ t) ↔
-    s.Nonempty ∧ t.Nonempty ∧ (Nontrivial s ∨ Nontrivial t) := by
-  simp_rw [← card_pos, ← one_lt_card_iff_nontrivial_coe, card_product]; apply Nat.one_lt_mul_iff
+lemma nontrivial_prod_iff : (s ×ˢ t).Nontrivial ↔
+    s.Nonempty ∧ t.Nonempty ∧ (s.Nontrivial ∨ t.Nontrivial) := by
+  simp_rw [← card_pos, ← one_lt_card_iff_nontrivial, card_product]; apply Nat.one_lt_mul_iff
 
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
     ((s ×ˢ t).filter fun x : α × β => p x.1 ∧ q x.2) = s.filter p ×ˢ t.filter q := by
feat: Finsets of cardinality > 1 in Pi types (#6818)

Add an equivalent condition for 1 < m * n in Nat, and two lemmas about Finsets of cardinality > 1.

Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>

Diff
@@ -140,6 +140,12 @@ theorem card_product (s : Finset α) (t : Finset β) : card (s ×ˢ t) = card s
   Multiset.card_product _ _
 #align finset.card_product Finset.card_product
 
+/-- The product of two Finsets is nontrivial iff both are nonempty
+  at least one of them is nontrivial. -/
+lemma nontrivial_prod_iff : Nontrivial (s ×ˢ t) ↔
+    s.Nonempty ∧ t.Nonempty ∧ (Nontrivial s ∨ Nontrivial t) := by
+  simp_rw [← card_pos, ← one_lt_card_iff_nontrivial_coe, card_product]; apply Nat.one_lt_mul_iff
+
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
     ((s ×ˢ t).filter fun x : α × β => p x.1 ∧ q x.2) = s.filter p ×ˢ t.filter q := by
   ext ⟨a, b⟩
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
@@ -25,7 +25,7 @@ This file defines finset constructions on the product type `α × β`. Beware no
 
 open Multiset
 
-variable {α β γ : Type _}
+variable {α β γ : Type*}
 
 namespace Finset
 
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,14 +2,11 @@
 Copyright (c) 2017 Microsoft Corporation. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Johannes Hölzl, Mario Carneiro, Oliver Nash
-
-! This file was ported from Lean 3 source module data.finset.prod
-! leanprover-community/mathlib commit 9003f28797c0664a49e4179487267c494477d853
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Data.Finset.Card
 
+#align_import data.finset.prod from "leanprover-community/mathlib"@"9003f28797c0664a49e4179487267c494477d853"
+
 /-!
 # Finsets in product types
 
chore: fix focusing dots (#5708)

This PR is the result of running

find . -type f -name "*.lean" -exec sed -i -E 's/^( +)\. /\1· /' {} \;
find . -type f -name "*.lean" -exec sed -i -E 'N;s/^( +·)\n +(.*)$/\1 \2/;P;D' {} \;

which firstly replaces . focusing dots with · and secondly removes isolated instances of such dots, unifying them with the following line. A new rule is placed in the style linter to verify this.

Diff
@@ -170,8 +170,8 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
       ext ⟨a, b⟩
       simp only [filter_union_right, mem_filter, mem_product]
       constructor <;> intro h <;> use h.1
-      . simp only [h.2, Function.comp_apply, Decidable.em, and_self]
-      . revert h
+      · simp only [h.2, Function.comp_apply, Decidable.em, and_self]
+      · revert h
         simp only [Function.comp_apply, and_imp]
         rintro _ _ (_|_) <;> simp [*]
     · apply Finset.disjoint_filter_filter'
refactor: use the typeclass SProd to implement overloaded notation · ×ˢ · (#4200)

Currently, the following notations are changed from · ×ˢ · because Lean 4 can't deal with ambiguous notations. | Definition | Notation | | :

Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com> Co-authored-by: Kyle Miller <kmill31415@gmail.com> Co-authored-by: Chris Hughes <chrishughes24@gmail.com>

Diff
@@ -44,69 +44,66 @@ protected def product (s : Finset α) (t : Finset β) : Finset (α × β) :=
   ⟨_, s.nodup.product t.nodup⟩
 #align finset.product Finset.product
 
---Porting note: Change notation from  "×ˢ" to "×ᶠ" to avoid ambiguity
-@[inherit_doc]
-infixr:82
-  " ×ᶠ " =>-- This notation binds more strongly than (pre)images, unions and intersections.
-  Finset.product
+instance instSProd : SProd (Finset α) (Finset β) (Finset (α × β)) where
+  sprod := Finset.product
 
 @[simp]
-theorem product_val : (s ×ᶠ t).1 = s.1 ×ˢ t.1 :=
+theorem product_val : (s ×ˢ t).1 = s.1 ×ˢ t.1 :=
   rfl
 #align finset.product_val Finset.product_val
 
 @[simp]
-theorem mem_product {p : α × β} : p ∈ s ×ᶠ t ↔ p.1 ∈ s ∧ p.2 ∈ t :=
+theorem mem_product {p : α × β} : p ∈ s ×ˢ t ↔ p.1 ∈ s ∧ p.2 ∈ t :=
   Multiset.mem_product
 #align finset.mem_product Finset.mem_product
 
-theorem mk_mem_product (ha : a ∈ s) (hb : b ∈ t) : (a, b) ∈ s ×ᶠ t :=
+theorem mk_mem_product (ha : a ∈ s) (hb : b ∈ t) : (a, b) ∈ s ×ˢ t :=
   mem_product.2 ⟨ha, hb⟩
 #align finset.mk_mem_product Finset.mk_mem_product
 
 @[simp, norm_cast]
 theorem coe_product (s : Finset α) (t : Finset β) :
-    (↑(s ×ᶠ t) : Set (α × β)) = (s : Set α) ×ˢ t :=
+    (↑(s ×ˢ t) : Set (α × β)) = (s : Set α) ×ˢ t :=
   Set.ext fun _ => Finset.mem_product
 #align finset.coe_product Finset.coe_product
 
-theorem subset_product_image_fst [DecidableEq α] : (s ×ᶠ t).image Prod.fst ⊆ s := fun i => by
+theorem subset_product_image_fst [DecidableEq α] : (s ×ˢ t).image Prod.fst ⊆ s := fun i => by
   simp (config := { contextual := true }) [mem_image]
 #align finset.subset_product_image_fst Finset.subset_product_image_fst
 
-theorem subset_product_image_snd [DecidableEq β] : (s ×ᶠ t).image Prod.snd ⊆ t := fun i => by
+theorem subset_product_image_snd [DecidableEq β] : (s ×ˢ t).image Prod.snd ⊆ t := fun i => by
   simp (config := { contextual := true }) [mem_image]
 #align finset.subset_product_image_snd Finset.subset_product_image_snd
 
-theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ᶠ t).image Prod.fst = s := by
+theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ˢ t).image Prod.fst = s := by
   ext i
   simp [mem_image, ht.bex]
 #align finset.product_image_fst Finset.product_image_fst
 
-theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ᶠ t).image Prod.snd = t := by
+theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ˢ t).image Prod.snd = t := by
   ext i
   simp [mem_image, ht.bex]
 #align finset.product_image_snd Finset.product_image_snd
 
 theorem subset_product [DecidableEq α] [DecidableEq β] {s : Finset (α × β)} :
-    s ⊆ s.image Prod.fst ×ᶠ s.image Prod.snd := fun _ hp =>
+    s ⊆ s.image Prod.fst ×ˢ s.image Prod.snd := fun _ hp =>
   mem_product.2 ⟨mem_image_of_mem _ hp, mem_image_of_mem _ hp⟩
 #align finset.subset_product Finset.subset_product
 
-theorem product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s ×ᶠ t ⊆ s' ×ᶠ t' := fun ⟨_, _⟩ h =>
+theorem product_subset_product (hs : s ⊆ s') (ht : t ⊆ t') : s ×ˢ t ⊆ s' ×ˢ t' := fun ⟨_, _⟩ h =>
   mem_product.2 ⟨hs (mem_product.1 h).1, ht (mem_product.1 h).2⟩
 #align finset.product_subset_product Finset.product_subset_product
 
-theorem product_subset_product_left (hs : s ⊆ s') : s ×ᶠ t ⊆ s' ×ᶠ t :=
+theorem product_subset_product_left (hs : s ⊆ s') : s ×ˢ t ⊆ s' ×ˢ t :=
   product_subset_product hs (Subset.refl _)
 #align finset.product_subset_product_left Finset.product_subset_product_left
 
-theorem product_subset_product_right (ht : t ⊆ t') : s ×ᶠ t ⊆ s ×ᶠ t' :=
+theorem product_subset_product_right (ht : t ⊆ t') : s ×ˢ t ⊆ s ×ˢ t' :=
   product_subset_product (Subset.refl _) ht
 #align finset.product_subset_product_right Finset.product_subset_product_right
 
 theorem map_swap_product (s : Finset α) (t : Finset β) :
-    (t ×ᶠ s).map ⟨Prod.swap, Prod.swap_injective⟩ = s ×ᶠ t :=
+    (t ×ˢ s).map ⟨Prod.swap, Prod.swap_injective⟩ = s ×ˢ t :=
   coe_injective <| by
     push_cast
     exact Set.image_swap_prod _ _
@@ -114,21 +111,21 @@ theorem map_swap_product (s : Finset α) (t : Finset β) :
 
 @[simp]
 theorem image_swap_product [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
-    (t ×ᶠ s).image Prod.swap = s ×ᶠ t :=
+    (t ×ˢ s).image Prod.swap = s ×ˢ t :=
   coe_injective <| by
     push_cast
     exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
 theorem product_eq_biUnion [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
-    s ×ᶠ t = s.biUnion fun a => t.image fun b => (a, b) :=
+    s ×ˢ t = s.biUnion fun a => t.image fun b => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_biUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion Finset.product_eq_biUnion
 
 theorem product_eq_biUnion_right [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
-    s ×ᶠ t = t.biUnion fun b => s.image fun a => (a, b) :=
+    s ×ˢ t = t.biUnion fun b => s.image fun a => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_biUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
@@ -137,34 +134,34 @@ theorem product_eq_biUnion_right [DecidableEq (α × β)] (s : Finset α) (t : F
 /-- See also `Finset.sup_product_left`. -/
 @[simp]
 theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
-    (s ×ᶠ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
+    (s ×ˢ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
   classical simp_rw [product_eq_biUnion, biUnion_biUnion, image_biUnion]
 #align finset.product_bUnion Finset.product_biUnion
 
 @[simp]
-theorem card_product (s : Finset α) (t : Finset β) : card (s ×ᶠ t) = card s * card t :=
+theorem card_product (s : Finset α) (t : Finset β) : card (s ×ˢ t) = card s * card t :=
   Multiset.card_product _ _
 #align finset.card_product Finset.card_product
 
 theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
-    ((s ×ᶠ t).filter fun x : α × β => p x.1 ∧ q x.2) = s.filter p ×ᶠ t.filter q := by
+    ((s ×ˢ t).filter fun x : α × β => p x.1 ∧ q x.2) = s.filter p ×ˢ t.filter q := by
   ext ⟨a, b⟩
   simp [mem_filter, mem_product, decide_eq_true_eq, and_comm, and_left_comm, and_assoc]
 #align finset.filter_product Finset.filter_product
 
 theorem filter_product_left (p : α → Prop) [DecidablePred p] :
-    ((s ×ᶠ t).filter fun x : α × β => p x.1) = s.filter p ×ᶠ t := by
+    ((s ×ˢ t).filter fun x : α × β => p x.1) = s.filter p ×ˢ t := by
   simpa using filter_product p fun _ => true
 #align finset.filter_product_left Finset.filter_product_left
 
 theorem filter_product_right (q : β → Prop) [DecidablePred q] :
-    ((s ×ᶠ t).filter fun x : α × β => q x.2) = s ×ᶠ t.filter q := by
+    ((s ×ˢ t).filter fun x : α × β => q x.2) = s ×ˢ t.filter q := by
   simpa using filter_product (fun _ : α => true) q
 #align finset.filter_product_right Finset.filter_product_right
 
 theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q : β → Prop)
     [DecidablePred p] [DecidablePred q] :
-    ((s ×ᶠ t).filter fun x : α × β => (p x.1) = (q x.2)).card =
+    ((s ×ˢ t).filter fun x : α × β => (p x.1) = (q x.2)).card =
       (s.filter p).card * (t.filter q).card +
         (s.filter (¬ p ·)).card * (t.filter (¬ q ·)).card := by
   classical
@@ -181,100 +178,100 @@ theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q
       exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
 
-theorem empty_product (t : Finset β) : (∅ : Finset α) ×ᶠ t = ∅ :=
+theorem empty_product (t : Finset β) : (∅ : Finset α) ×ˢ t = ∅ :=
   rfl
 #align finset.empty_product Finset.empty_product
 
-theorem product_empty (s : Finset α) : s ×ᶠ (∅ : Finset β) = ∅ :=
+theorem product_empty (s : Finset α) : s ×ˢ (∅ : Finset β) = ∅ :=
   eq_empty_of_forall_not_mem fun _ h => not_mem_empty _ (Finset.mem_product.1 h).2
 #align finset.product_empty Finset.product_empty
 
-theorem Nonempty.product (hs : s.Nonempty) (ht : t.Nonempty) : (s ×ᶠ t).Nonempty :=
+theorem Nonempty.product (hs : s.Nonempty) (ht : t.Nonempty) : (s ×ˢ t).Nonempty :=
   let ⟨x, hx⟩ := hs
   let ⟨y, hy⟩ := ht
   ⟨(x, y), mem_product.2 ⟨hx, hy⟩⟩
 #align finset.nonempty.product Finset.Nonempty.product
 
-theorem Nonempty.fst (h : (s ×ᶠ t).Nonempty) : s.Nonempty :=
+theorem Nonempty.fst (h : (s ×ˢ t).Nonempty) : s.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.1, (mem_product.1 hxy).1⟩
 #align finset.nonempty.fst Finset.Nonempty.fst
 
-theorem Nonempty.snd (h : (s ×ᶠ t).Nonempty) : t.Nonempty :=
+theorem Nonempty.snd (h : (s ×ˢ t).Nonempty) : t.Nonempty :=
   let ⟨xy, hxy⟩ := h
   ⟨xy.2, (mem_product.1 hxy).2⟩
 #align finset.nonempty.snd Finset.Nonempty.snd
 
 @[simp]
-theorem nonempty_product : (s ×ᶠ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
+theorem nonempty_product : (s ×ˢ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
   ⟨fun h => ⟨h.fst, h.snd⟩, fun h => h.1.product h.2⟩
 #align finset.nonempty_product Finset.nonempty_product
 
 @[simp]
-theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ᶠ t = ∅ ↔ s = ∅ ∨ t = ∅ := by
+theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ˢ t = ∅ ↔ s = ∅ ∨ t = ∅ := by
   rw [← not_nonempty_iff_eq_empty, nonempty_product, not_and_or, not_nonempty_iff_eq_empty,
     not_nonempty_iff_eq_empty]
 #align finset.product_eq_empty Finset.product_eq_empty
 
 @[simp]
 theorem singleton_product {a : α} :
-    ({a} : Finset α) ×ᶠ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ := by
+    ({a} : Finset α) ×ˢ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ := by
   ext ⟨x, y⟩
   simp [and_left_comm, eq_comm]
 #align finset.singleton_product Finset.singleton_product
 
 @[simp]
-theorem product_singleton {b : β} : s ×ᶠ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
+theorem product_singleton {b : β} : s ×ˢ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
   ext ⟨x, y⟩
   simp [and_left_comm, eq_comm]
 #align finset.product_singleton Finset.product_singleton
 
 theorem singleton_product_singleton {a : α} {b : β} :
-    ({a} : Finset α) ×ᶠ ({b} : Finset β) = {(a, b)} := by
+    ({a} ×ˢ {b} : Finset _) = {(a, b)} := by
   simp only [product_singleton, Function.Embedding.coeFn_mk, map_singleton]
 #align finset.singleton_product_singleton Finset.singleton_product_singleton
 
 @[simp]
-theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ᶠ t = s ×ᶠ t ∪ s' ×ᶠ t := by
+theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ˢ t = s ×ˢ t ∪ s' ×ˢ t := by
   ext ⟨x, y⟩
   simp only [or_and_right, mem_union, mem_product]
 #align finset.union_product Finset.union_product
 
 @[simp]
-theorem product_union [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∪ t') = s ×ᶠ t ∪ s ×ᶠ t' := by
+theorem product_union [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∪ t') = s ×ˢ t ∪ s ×ˢ t' := by
   ext ⟨x, y⟩
   simp only [and_or_left, mem_union, mem_product]
 #align finset.product_union Finset.product_union
 
-theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ᶠ t = s ×ᶠ t ∩ s' ×ᶠ t := by
+theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ˢ t = s ×ˢ t ∩ s' ×ˢ t := by
   ext ⟨x, y⟩
   simp only [← and_and_right, mem_inter, mem_product]
 #align finset.inter_product Finset.inter_product
 
-theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∩ t') = s ×ᶠ t ∩ s ×ᶠ t' := by
+theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ˢ (t ∩ t') = s ×ˢ t ∩ s ×ˢ t' := by
   ext ⟨x, y⟩
   simp only [← and_and_left, mem_inter, mem_product]
 #align finset.product_inter Finset.product_inter
 
 theorem product_inter_product [DecidableEq α] [DecidableEq β] :
-    s ×ᶠ t ∩ s' ×ᶠ t' = (s ∩ s') ×ᶠ (t ∩ t') := by
+    s ×ˢ t ∩ s' ×ˢ t' = (s ∩ s') ×ˢ (t ∩ t') := by
   ext ⟨x, y⟩
   simp only [and_assoc, and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
 
-theorem disjoint_product : Disjoint (s ×ᶠ t) (s' ×ᶠ t') ↔ Disjoint s s' ∨ Disjoint t t' := by
+theorem disjoint_product : Disjoint (s ×ˢ t) (s' ×ˢ t') ↔ Disjoint s s' ∨ Disjoint t t' := by
   simp_rw [← disjoint_coe, coe_product, Set.disjoint_prod]
 #align finset.disjoint_product Finset.disjoint_product
 
 @[simp]
 theorem disjUnion_product (hs : Disjoint s s') :
-    s.disjUnion s' hs ×ᶠ t = (s ×ᶠ t).disjUnion (s' ×ᶠ t) (disjoint_product.mpr <| Or.inl hs) :=
+    s.disjUnion s' hs ×ˢ t = (s ×ˢ t).disjUnion (s' ×ˢ t) (disjoint_product.mpr <| Or.inl hs) :=
   eq_of_veq <| Multiset.add_product _ _ _
 #align finset.disj_union_product Finset.disjUnion_product
 
 @[simp]
 theorem product_disjUnion (ht : Disjoint t t') :
-    s ×ᶠ t.disjUnion t' ht = (s ×ᶠ t).disjUnion (s ×ᶠ t') (disjoint_product.mpr <| Or.inr ht) :=
+    s ×ˢ t.disjUnion t' ht = (s ×ˢ t).disjUnion (s ×ˢ t') (disjoint_product.mpr <| Or.inr ht) :=
   eq_of_veq <| Multiset.product_add _ _ _
 #align finset.product_disj_union Finset.product_disjUnion
 
@@ -287,13 +284,13 @@ variable [DecidableEq α] (s t : Finset α)
 /-- Given a finite set `s`, the diagonal, `s.diag` is the set of pairs of the form `(a, a)` for
 `a ∈ s`. -/
 def diag :=
-  (s ×ᶠ s).filter fun a : α × α => a.fst = a.snd
+  (s ×ˢ s).filter fun a : α × α => a.fst = a.snd
 #align finset.diag Finset.diag
 
 /-- Given a finite set `s`, the off-diagonal, `s.offDiag` is the set of pairs `(a, b)` with `a ≠ b`
 for `a, b ∈ s`. -/
 def offDiag :=
-  (s ×ᶠ s).filter fun a : α × α => a.fst ≠ a.snd
+  (s ×ˢ s).filter fun a : α × α => a.fst ≠ a.snd
 #align finset.off_diag Finset.offDiag
 
 variable {s} {x : α × α}
@@ -364,21 +361,21 @@ theorem offDiag_empty : (∅ : Finset α).offDiag = ∅ :=
 #align finset.off_diag_empty Finset.offDiag_empty
 
 @[simp]
-theorem diag_union_offDiag : s.diag ∪ s.offDiag = s ×ᶠ s := by
-  conv_rhs => rw [← filter_union_filter_neg_eq (fun a => a.1 = a.2) (s ×ᶠ s)]
+theorem diag_union_offDiag : s.diag ∪ s.offDiag = s ×ˢ s := by
+  conv_rhs => rw [← filter_union_filter_neg_eq (fun a => a.1 = a.2) (s ×ˢ s)]
 #align finset.diag_union_off_diag Finset.diag_union_offDiag
 
 @[simp]
 theorem disjoint_diag_offDiag : Disjoint s.diag s.offDiag :=
-  disjoint_filter_filter_neg (s ×ᶠ s) (s ×ᶠ s) (fun a => a.1 = a.2)
+  disjoint_filter_filter_neg (s ×ˢ s) (s ×ˢ s) (fun a => a.1 = a.2)
 #align finset.disjoint_diag_off_diag Finset.disjoint_diag_offDiag
 
-theorem product_sdiff_diag : s ×ᶠ s \ s.diag = s.offDiag := by
+theorem product_sdiff_diag : s ×ˢ s \ s.diag = s.offDiag := by
   rw [← diag_union_offDiag, union_comm, union_sdiff_self,
     sdiff_eq_self_of_disjoint (disjoint_diag_offDiag _).symm]
 #align finset.product_sdiff_diag Finset.product_sdiff_diag
 
-theorem product_sdiff_offDiag : s ×ᶠ s \ s.offDiag = s.diag := by
+theorem product_sdiff_offDiag : s ×ˢ s \ s.offDiag = s.diag := by
   rw [← diag_union_offDiag, union_sdiff_self, sdiff_eq_self_of_disjoint (disjoint_diag_offDiag _)]
 #align finset.product_sdiff_off_diag Finset.product_sdiff_offDiag
 
@@ -400,7 +397,7 @@ theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag := by
 variable {s t}
 
 theorem offDiag_union (h : Disjoint s t) :
-    (s ∪ t).offDiag = s.offDiag ∪ t.offDiag ∪ s ×ᶠ t ∪ t ×ᶠ s :=
+    (s ∪ t).offDiag = s.offDiag ∪ t.offDiag ∪ s ×ˢ t ∪ t ×ˢ s :=
   coe_injective <| by
     push_cast
     exact Set.offDiag_union (disjoint_coe.2 h)
@@ -420,7 +417,7 @@ theorem diag_insert : (insert a s).diag = insert (a, a) s.diag := by
   rw [insert_eq, insert_eq, diag_union, diag_singleton]
 #align finset.diag_insert Finset.diag_insert
 
-theorem offDiag_insert (has : a ∉ s) : (insert a s).offDiag = s.offDiag ∪ {a} ×ᶠ s ∪ s ×ᶠ {a} := by
+theorem offDiag_insert (has : a ∉ s) : (insert a s).offDiag = s.offDiag ∪ {a} ×ˢ s ∪ s ×ˢ {a} := by
   rw [insert_eq, union_comm, offDiag_union (disjoint_singleton_right.2 has), offDiag_singleton,
     union_empty, union_right_comm]
 #align finset.off_diag_insert Finset.offDiag_insert
chore: Rename to sSup/iSup (#3938)

As discussed on Zulip

Renames

  • supₛsSup
  • infₛsInf
  • supᵢiSup
  • infᵢiInf
  • bsupₛbsSup
  • binfₛbsInf
  • bsupᵢbiSup
  • binfᵢbiInf
  • csupₛcsSup
  • cinfₛcsInf
  • csupᵢciSup
  • cinfᵢciInf
  • unionₛsUnion
  • interₛsInter
  • unionᵢiUnion
  • interᵢiInter
  • bunionₛbsUnion
  • binterₛbsInter
  • bunionᵢbiUnion
  • binterᵢbiInter

Co-authored-by: Parcly Taxel <reddeloostw@gmail.com>

Diff
@@ -120,26 +120,26 @@ theorem image_swap_product [DecidableEq (α × β)] (s : Finset α) (t : Finset
     exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
-theorem product_eq_bunionᵢ [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
-    s ×ᶠ t = s.bunionᵢ fun a => t.image fun b => (a, b) :=
+theorem product_eq_biUnion [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
+    s ×ᶠ t = s.biUnion fun a => t.image fun b => (a, b) :=
   ext fun ⟨x, y⟩ => by
-    simp only [mem_product, mem_bunionᵢ, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
+    simp only [mem_product, mem_biUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
-#align finset.product_eq_bUnion Finset.product_eq_bunionᵢ
+#align finset.product_eq_bUnion Finset.product_eq_biUnion
 
-theorem product_eq_bunionᵢ_right [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
-    s ×ᶠ t = t.bunionᵢ fun b => s.image fun a => (a, b) :=
+theorem product_eq_biUnion_right [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
+    s ×ᶠ t = t.biUnion fun b => s.image fun a => (a, b) :=
   ext fun ⟨x, y⟩ => by
-    simp only [mem_product, mem_bunionᵢ, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
+    simp only [mem_product, mem_biUnion, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
-#align finset.product_eq_bUnion_right Finset.product_eq_bunionᵢ_right
+#align finset.product_eq_bUnion_right Finset.product_eq_biUnion_right
 
 /-- See also `Finset.sup_product_left`. -/
 @[simp]
-theorem product_bunionᵢ [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
-    (s ×ᶠ t).bunionᵢ f = s.bunionᵢ fun a => t.bunionᵢ fun b => f (a, b) := by
-  classical simp_rw [product_eq_bunionᵢ, bunionᵢ_bunionᵢ, image_bunionᵢ]
-#align finset.product_bUnion Finset.product_bunionᵢ
+theorem product_biUnion [DecidableEq γ] (s : Finset α) (t : Finset β) (f : α × β → Finset γ) :
+    (s ×ᶠ t).biUnion f = s.biUnion fun a => t.biUnion fun b => f (a, b) := by
+  classical simp_rw [product_eq_biUnion, biUnion_biUnion, image_biUnion]
+#align finset.product_bUnion Finset.product_biUnion
 
 @[simp]
 theorem card_product (s : Finset α) (t : Finset β) : card (s ×ᶠ t) = card s * card t :=
chore: bye-bye, solo bys! (#3825)

This PR puts, with one exception, every single remaining by that lies all by itself on its own line to the previous line, thus matching the current behaviour of start-port.sh. The exception is when the by begins the second or later argument to a tuple or anonymous constructor; see https://github.com/leanprover-community/mathlib4/pull/3825#discussion_r1186702599.

Essentially this is s/\n *by$/ by/g, but with manual editing to satisfy the linter's max-100-char-line requirement. The Python style linter is also modified to catch these "isolated bys".

Diff
@@ -78,14 +78,12 @@ theorem subset_product_image_snd [DecidableEq β] : (s ×ᶠ t).image Prod.snd 
   simp (config := { contextual := true }) [mem_image]
 #align finset.subset_product_image_snd Finset.subset_product_image_snd
 
-theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ᶠ t).image Prod.fst = s :=
-  by
+theorem product_image_fst [DecidableEq α] (ht : t.Nonempty) : (s ×ᶠ t).image Prod.fst = s := by
   ext i
   simp [mem_image, ht.bex]
 #align finset.product_image_fst Finset.product_image_fst
 
-theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ᶠ t).image Prod.snd = t :=
-  by
+theorem product_image_snd [DecidableEq β] (ht : s.Nonempty) : (s ×ᶠ t).image Prod.snd = t := by
   ext i
   simp [mem_image, ht.bex]
 #align finset.product_image_snd Finset.product_image_snd
@@ -219,15 +217,14 @@ theorem product_eq_empty {s : Finset α} {t : Finset β} : s ×ᶠ t = ∅ ↔ s
 #align finset.product_eq_empty Finset.product_eq_empty
 
 @[simp]
-theorem singleton_product {a : α} : ({a} : Finset α) ×ᶠ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ :=
-  by
+theorem singleton_product {a : α} :
+    ({a} : Finset α) ×ᶠ t = t.map ⟨Prod.mk a, Prod.mk.inj_left _⟩ := by
   ext ⟨x, y⟩
   simp [and_left_comm, eq_comm]
 #align finset.singleton_product Finset.singleton_product
 
 @[simp]
-theorem product_singleton {b : β} : s ×ᶠ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ :=
-  by
+theorem product_singleton {b : β} : s ×ᶠ {b} = s.map ⟨fun i => (i, b), Prod.mk.inj_right _⟩ := by
   ext ⟨x, y⟩
   simp [and_left_comm, eq_comm]
 #align finset.product_singleton Finset.product_singleton
@@ -238,34 +235,29 @@ theorem singleton_product_singleton {a : α} {b : β} :
 #align finset.singleton_product_singleton Finset.singleton_product_singleton
 
 @[simp]
-theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ᶠ t = s ×ᶠ t ∪ s' ×ᶠ t :=
-  by
+theorem union_product [DecidableEq α] [DecidableEq β] : (s ∪ s') ×ᶠ t = s ×ᶠ t ∪ s' ×ᶠ t := by
   ext ⟨x, y⟩
   simp only [or_and_right, mem_union, mem_product]
 #align finset.union_product Finset.union_product
 
 @[simp]
-theorem product_union [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∪ t') = s ×ᶠ t ∪ s ×ᶠ t' :=
-  by
+theorem product_union [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∪ t') = s ×ᶠ t ∪ s ×ᶠ t' := by
   ext ⟨x, y⟩
   simp only [and_or_left, mem_union, mem_product]
 #align finset.product_union Finset.product_union
 
-theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ᶠ t = s ×ᶠ t ∩ s' ×ᶠ t :=
-  by
+theorem inter_product [DecidableEq α] [DecidableEq β] : (s ∩ s') ×ᶠ t = s ×ᶠ t ∩ s' ×ᶠ t := by
   ext ⟨x, y⟩
   simp only [← and_and_right, mem_inter, mem_product]
 #align finset.inter_product Finset.inter_product
 
-theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∩ t') = s ×ᶠ t ∩ s ×ᶠ t' :=
-  by
+theorem product_inter [DecidableEq α] [DecidableEq β] : s ×ᶠ (t ∩ t') = s ×ᶠ t ∩ s ×ᶠ t' := by
   ext ⟨x, y⟩
   simp only [← and_and_left, mem_inter, mem_product]
 #align finset.product_inter Finset.product_inter
 
 theorem product_inter_product [DecidableEq α] [DecidableEq β] :
-    s ×ᶠ t ∩ s' ×ᶠ t' = (s ∩ s') ×ᶠ (t ∩ t') :=
-  by
+    s ×ᶠ t ∩ s' ×ᶠ t' = (s ∩ s') ×ᶠ (t ∩ t') := by
   ext ⟨x, y⟩
   simp only [and_assoc, and_left_comm, mem_inter, mem_product]
 #align finset.product_inter_product Finset.product_inter_product
@@ -324,8 +316,7 @@ theorem coe_offDiag : (s.offDiag : Set (α × α)) = (s : Set α).offDiag :=
 #align finset.coe_off_diag Finset.coe_offDiag
 
 @[simp]
-theorem diag_card : (diag s).card = s.card :=
-  by
+theorem diag_card : (diag s).card = s.card := by
   suffices diag s = s.image fun a => (a, a) by
     rw [this]
     apply card_image_of_injOn
@@ -401,8 +392,7 @@ theorem offDiag_inter : (s ∩ t).offDiag = s.offDiag ∩ t.offDiag :=
     exact Set.offDiag_inter _ _
 #align finset.off_diag_inter Finset.offDiag_inter
 
-theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag :=
-  by
+theorem diag_union : (s ∪ t).diag = s.diag ∪ t.diag := by
   ext ⟨i, j⟩
   simp only [mem_diag, mem_union, or_and_right]
 #align finset.diag_union Finset.diag_union
feat: quick version of mono tactic (#1740)

This is an extremely partial port of the mono* tactic from Lean 3, implemented as a macro on top of solve_by_elim. The original mono had many configuration options and no documentation, so quite a bit is missing (and almost all the Lean 3 tests fail). Nonetheless I think it's worth merging this, because

  • it will get rid of errors in mathport output which come from lemmas being tagged with a nonexistent attribute @[mono]
  • in most mathlib3 uses of mono, only the basic version was used, not the various configuration options; thus I would guess that this version of mono will succeed fairly often in the port even though it fails nearly all the tests

Co-authored-by: thorimur <68410468+thorimur@users.noreply.github.com>

Diff
@@ -352,12 +352,12 @@ theorem offDiag_card : (offDiag s).card = s.card * s.card - s.card :=
      conv_rhs => rw [← filter_card_add_filter_neg_card_eq_card (fun a => a.1 = a.2)]
 #align finset.off_diag_card Finset.offDiag_card
 
---@[mono] Porting note: mono not implemented yet
+@[mono]
 theorem diag_mono : Monotone (diag : Finset α → Finset (α × α)) := fun _ _ h _ hx =>
   mem_diag.2 <| And.imp_left (@h _) <| mem_diag.1 hx
 #align finset.diag_mono Finset.diag_mono
 
---@[mono] Porting note: mono not implemented yet
+@[mono]
 theorem offDiag_mono : Monotone (offDiag : Finset α → Finset (α × α)) := fun _ _ h _ hx =>
   mem_offDiag.2 <| And.imp (@h _) (And.imp_left <| @h _) <| mem_offDiag.1 hx
 #align finset.off_diag_mono Finset.offDiag_mono
feat: port Data.Finset.Functor (#1974)
Diff
@@ -115,21 +115,21 @@ theorem map_swap_product (s : Finset α) (t : Finset β) :
 #align finset.map_swap_product Finset.map_swap_product
 
 @[simp]
-theorem image_swap_product [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
+theorem image_swap_product [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
     (t ×ᶠ s).image Prod.swap = s ×ᶠ t :=
   coe_injective <| by
     push_cast
     exact Set.image_swap_prod _ _
 #align finset.image_swap_product Finset.image_swap_product
 
-theorem product_eq_bunionᵢ [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
+theorem product_eq_bunionᵢ [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
     s ×ᶠ t = s.bunionᵢ fun a => t.image fun b => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bunionᵢ, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
       exists_and_left, exists_eq_right, exists_eq_left]
 #align finset.product_eq_bUnion Finset.product_eq_bunionᵢ
 
-theorem product_eq_bunionᵢ_right [DecidableEq α] [DecidableEq β] (s : Finset α) (t : Finset β) :
+theorem product_eq_bunionᵢ_right [DecidableEq (α × β)] (s : Finset α) (t : Finset β) :
     s ×ᶠ t = t.bunionᵢ fun b => s.image fun a => (a, b) :=
   ext fun ⟨x, y⟩ => by
     simp only [mem_product, mem_bunionᵢ, mem_image, exists_prop, Prod.mk.inj_iff, and_left_comm,
chore: revert Multiset and Finset API to use Prop instead of Bool (#1652)

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

Diff
@@ -148,40 +148,37 @@ theorem card_product (s : Finset α) (t : Finset β) : card (s ×ᶠ t) = card s
   Multiset.card_product _ _
 #align finset.card_product Finset.card_product
 
-theorem filter_product (p : α → Bool) (q : β → Bool) :
-    ((s ×ᶠ t).filter fun x : α × β => p x.1 && q x.2) = s.filter p ×ᶠ t.filter q := by
+theorem filter_product (p : α → Prop) (q : β → Prop) [DecidablePred p] [DecidablePred q] :
+    ((s ×ᶠ t).filter fun x : α × β => p x.1 ∧ q x.2) = s.filter p ×ᶠ t.filter q := by
   ext ⟨a, b⟩
   simp [mem_filter, mem_product, decide_eq_true_eq, and_comm, and_left_comm, and_assoc]
 #align finset.filter_product Finset.filter_product
 
-theorem filter_product_left (p : α → Bool) :
+theorem filter_product_left (p : α → Prop) [DecidablePred p] :
     ((s ×ᶠ t).filter fun x : α × β => p x.1) = s.filter p ×ᶠ t := by
   simpa using filter_product p fun _ => true
 #align finset.filter_product_left Finset.filter_product_left
 
-theorem filter_product_right (q : β → Bool) :
+theorem filter_product_right (q : β → Prop) [DecidablePred q] :
     ((s ×ᶠ t).filter fun x : α × β => q x.2) = s ×ᶠ t.filter q := by
   simpa using filter_product (fun _ : α => true) q
 #align finset.filter_product_right Finset.filter_product_right
 
-theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Bool) (q : β → Bool) :
-    ((s ×ᶠ t).filter fun x : α × β => (p x.1) == (q x.2)).card =
+theorem filter_product_card (s : Finset α) (t : Finset β) (p : α → Prop) (q : β → Prop)
+    [DecidablePred p] [DecidablePred q] :
+    ((s ×ᶠ t).filter fun x : α × β => (p x.1) = (q x.2)).card =
       (s.filter p).card * (t.filter q).card +
-        (s.filter (not ∘ p)).card * (t.filter (not ∘ q)).card := by
+        (s.filter (¬ p ·)).card * (t.filter (¬ q ·)).card := by
   classical
     rw [← card_product, ← card_product, ← filter_product, ← filter_product, ← card_union_eq]
     · apply congr_arg
       ext ⟨a, b⟩
       simp only [filter_union_right, mem_filter, mem_product]
       constructor <;> intro h <;> use h.1
-      . simp only [beq_iff_eq] at h
-        simp only [h.2, Bool.and_self, Function.comp_apply, Bool.not_eq_true', Bool.decide_or,
-        Bool.decide_coe, Bool.or_eq_true, decide_eq_true_eq]
-        cases q b <;> simp [*]
+      . simp only [h.2, Function.comp_apply, Decidable.em, and_self]
       . revert h
-        simp only [Bool.and_eq_true, Function.comp_apply, Bool.not_eq_true', Bool.decide_or,
-          Bool.decide_and, Bool.decide_coe, Bool.or_eq_true, decide_eq_true_eq, beq_iff_eq, and_imp]
-        cases p a <;> cases q b <;> simp [*] at *
+        simp only [Function.comp_apply, and_imp]
+        rintro _ _ (_|_) <;> simp [*]
     · apply Finset.disjoint_filter_filter'
       exact (disjoint_compl_right.inf_left _).inf_right _
 #align finset.filter_product_card Finset.filter_product_card
@@ -353,7 +350,6 @@ theorem offDiag_card : (offDiag s).card = s.card * s.card - s.card :=
     rw [this]
   by rw [← card_product, diag, offDiag]
      conv_rhs => rw [← filter_card_add_filter_neg_card_eq_card (fun a => a.1 = a.2)]
-     simp
 #align finset.off_diag_card Finset.offDiag_card
 
 --@[mono] Porting note: mono not implemented yet
@@ -379,14 +375,11 @@ theorem offDiag_empty : (∅ : Finset α).offDiag = ∅ :=
 @[simp]
 theorem diag_union_offDiag : s.diag ∪ s.offDiag = s ×ᶠ s := by
   conv_rhs => rw [← filter_union_filter_neg_eq (fun a => a.1 = a.2) (s ×ᶠ s)]
-  simp [diag, offDiag]
 #align finset.diag_union_off_diag Finset.diag_union_offDiag
 
 @[simp]
-theorem disjoint_diag_offDiag : Disjoint s.diag s.offDiag := by
-  rw [diag, offDiag]
-  convert disjoint_filter_filter_neg (s ×ᶠ s) (s ×ᶠ s) (fun a => a.1 = a.2)
-  simp
+theorem disjoint_diag_offDiag : Disjoint s.diag s.offDiag :=
+  disjoint_filter_filter_neg (s ×ᶠ s) (s ×ᶠ s) (fun a => a.1 = a.2)
 #align finset.disjoint_diag_off_diag Finset.disjoint_diag_offDiag
 
 theorem product_sdiff_diag : s ×ᶠ s \ s.diag = s.offDiag := by
feat: port Data.Finset.Prod (#1599)

Co-authored-by: Chris Hughes <33847686+ChrisHughes24@users.noreply.github.com>

Dependencies 2 + 154

155 files ported (98.7%)
71605 lines ported (99.8%)
Show graph

The unported dependencies are