order.game_addMathlib.Order.GameAdd

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)

(last sync)

doc(order/game_add): minor doc improvement (#18525)

Ported along with other changes to the file: https://github.com/leanprover-community/mathlib4/pull/2532

Diff
@@ -17,6 +17,8 @@ This file defines, given relations `rα : α → α → Prop` and `rβ : β →
 decreasing either entry (with respect to `rα` and `rβ`). It is so called since it models the
 subsequency relation on the addition of combinatorial games.
 
+We also define `sym2.game_add`, which is the unordered pair analog of `prod.game_add`.
+
 ## Main definitions and results
 
 - `prod.game_add`: the game addition relation on ordered pairs.
@@ -43,7 +45,9 @@ variables (rα rβ)
   that `a₂ ⟶ a₁` is a valid move in game `α`, and `rβ b₁ b₂` means that `b₂ ⟶ b₁` is a valid move
   in game `β`, then `game_add rα rβ` specifies the valid moves in the juxtaposition of `α` and `β`:
   the player is free to choose one of the games and make a move in it, while leaving the other game
-  unchanged. -/
+  unchanged.
+
+  See `sym2.game_add` for the unordered pair analog. -/
 inductive game_add : α × β → α × β → Prop
 | fst {a₁ a₂ b} : rα a₁ a₂ → game_add (a₁, b) (a₂, b)
 | snd {a b₁ b₂} : rβ b₁ b₂ → game_add (a, b₁) (a, b₂)
@@ -131,7 +135,10 @@ end prod
 
 namespace sym2
 
-/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry. -/
+/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry with
+  respect to the relation `rα`.
+
+  See `prod.game_add` for the ordered pair analog. -/
 def game_add (rα : α → α → Prop): sym2 α → sym2 α → Prop :=
 sym2.lift₂
 ⟨λ a₁ b₁ a₂ b₂, prod.game_add rα rα (a₁, b₁) (a₂, b₂) ∨ prod.game_add rα rα (b₁, a₁) (a₂, b₂),

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(order/game_add): sym2.game_add (#18287)

We define sym2.game_add, which is a relation sym2 α → sym2 α → Prop which expresses that one pair may be obtained from the other by decreasing either entry. We add a basic API, and prove well-foundedness.

Pair: https://github.com/leanprover-community/mathlib4/pull/2532

Diff
@@ -3,7 +3,7 @@ Copyright (c) 2022 Junyan Xu. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 -/
-import order.basic
+import data.sym.sym2
 import logic.relation
 
 /-!
@@ -23,15 +23,19 @@ subsequency relation on the addition of combinatorial games.
 - `well_founded.prod_game_add`: formalizes induction on ordered pairs, where exactly one entry
   decreases at a time.
 
-## Todo
-
-- Define `sym2.game_add`.
+- `sym2.game_add`: the game addition relation on unordered pairs.
+- `well_founded.sym2_game_add`: formalizes induction on unordered pairs, where exactly one entry
+  decreases at a time.
 -/
 
-variables {α β : Type*} (rα : α → α → Prop) (rβ : β → β → Prop)
+variables {α β : Type*} {rα : α → α → Prop} {rβ : β → β → Prop}
+
+/-! ### `prod.game_add` -/
 
 namespace prod
 
+variables (rα rβ)
+
 /-- `prod.game_add rα rβ x y` means that `x` can be reached from `y` by decreasing either entry with
   respect to the relations `rα` and `rβ`.
 
@@ -63,6 +67,10 @@ game_add_iff
   game_add rβ rα a.swap b.swap ↔ game_add rα rβ a b :=
 λ ⟨a₁, b₁⟩ ⟨a₂, b₂⟩, by rw [prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm]
 
+lemma game_add_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
+  game_add rα rβ (a₁, b₁) (a₂, b₂) ↔ game_add rβ rα (b₁, a₁) (b₂, a₂) :=
+game_add_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
+
 /-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 lemma game_add_le_lex : game_add rα rβ ≤ prod.lex rα rβ :=
 λ _ _ h, h.rec (λ _ _ b, prod.lex.left b b) (λ a _ _, prod.lex.right a)
@@ -76,8 +84,6 @@ end
 
 end prod
 
-variables {rα rβ}
-
 /-- If `a` is accessible under `rα` and `b` is accessible under `rβ`, then `(a, b)` is
   accessible under `prod.game_add rα rβ`. Notice that `prod.lex_accessible` requires the
   stronger condition `∀ b, acc rβ b`. -/
@@ -110,7 +116,7 @@ def game_add.fix {C : α → β → Sort*} (hα : well_founded rα) (hβ : well_
 lemma game_add.fix_eq {C : α → β → Sort*} (hα : well_founded rα) (hβ : well_founded rβ)
   (IH : Π a₁ b₁, (Π a₂ b₂, game_add rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
   game_add.fix hα hβ IH a b = IH a b (λ a' b' h, game_add.fix hα hβ IH a' b') :=
-by { rw [game_add.fix, well_founded.fix_eq], refl }
+well_founded.fix_eq _ _ _
 
 /-- Induction on the well-founded `prod.game_add` relation.
 
@@ -120,3 +126,84 @@ lemma game_add.induction {C : α → β → Prop} : well_founded rα → well_fo
 game_add.fix
 
 end prod
+
+/-! ### `sym2.game_add` -/
+
+namespace sym2
+
+/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry. -/
+def game_add (rα : α → α → Prop): sym2 α → sym2 α → Prop :=
+sym2.lift₂
+⟨λ a₁ b₁ a₂ b₂, prod.game_add rα rα (a₁, b₁) (a₂, b₂) ∨ prod.game_add rα rα (b₁, a₁) (a₂, b₂),
+  λ a₁ b₁ a₂ b₂, begin
+    rw [prod.game_add_swap_swap_mk _ _ b₁ b₂ a₁ a₂, prod.game_add_swap_swap_mk _ _ a₁ b₂ b₁ a₂],
+    simp [or_comm]
+  end⟩
+
+variable {rα}
+
+lemma game_add_iff : ∀ {x y : α × α}, game_add rα ⟦x⟧ ⟦y⟧ ↔
+  prod.game_add rα rα x y ∨ prod.game_add rα rα x.swap y :=
+by { rintros ⟨_, _⟩ ⟨_, _⟩, refl }
+
+lemma game_add_mk_iff {a₁ a₂ b₁ b₂ : α} : game_add rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ ↔
+  prod.game_add rα rα (a₁, b₁) (a₂, b₂) ∨ prod.game_add rα rα (b₁, a₁) (a₂, b₂) :=
+iff.rfl
+
+lemma _root_.prod.game_add.to_sym2 {a₁ a₂ b₁ b₂ : α}
+  (h : prod.game_add rα rα (a₁, b₁) (a₂, b₂)) : sym2.game_add rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ :=
+game_add_mk_iff.2 $ or.inl $ h
+
+lemma game_add.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : game_add rα ⟦(a₁, b)⟧ ⟦(a₂, b)⟧ :=
+(prod.game_add.fst h).to_sym2
+
+lemma game_add.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : game_add rα ⟦(a, b₁)⟧ ⟦(a, b₂)⟧ :=
+(prod.game_add.snd h).to_sym2
+
+lemma game_add.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : game_add rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
+by { rw sym2.eq_swap, exact game_add.snd h }
+
+lemma game_add.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : game_add rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
+by { rw sym2.eq_swap, exact game_add.fst h }
+
+end sym2
+
+lemma acc.sym2_game_add {a b} (ha : acc rα a) (hb : acc rα b) : acc (sym2.game_add rα) ⟦(a, b)⟧ :=
+begin
+  induction ha with a ha iha generalizing b,
+  induction hb with b hb ihb,
+  refine acc.intro _ (λ s, _),
+  induction s using sym2.induction_on with c d,
+  rintros ((rc | rd) | (rd | rc)),
+  { exact iha c rc ⟨b, hb⟩ },
+  { exact ihb d rd },
+  { rw sym2.eq_swap,
+    exact iha d rd ⟨b, hb⟩ },
+  { rw sym2.eq_swap,
+    exact ihb c rc }
+end
+
+/-- The `sym2.game_add` relation on well-founded inputs is well-founded. -/
+lemma well_founded.sym2_game_add (h : well_founded rα) : well_founded (sym2.game_add rα) :=
+⟨λ i, sym2.induction_on i $ λ x y, (h.apply x).sym2_game_add (h.apply y)⟩
+
+namespace sym2
+
+/-- Recursion on the well-founded `sym2.game_add` relation. -/
+def game_add.fix {C : α → α → Sort*} (hr : well_founded rα)
+  (IH : Π a₁ b₁, (Π a₂ b₂, sym2.game_add rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+  C a b :=
+@well_founded.fix (α × α) (λ x, C x.1 x.2) _ hr.sym2_game_add.of_quotient_lift₂
+  (λ ⟨x₁, x₂⟩ IH', IH x₁ x₂ $ λ a' b', IH' ⟨a', b'⟩) (a, b)
+
+lemma game_add.fix_eq {C : α → α → Sort*} (hr : well_founded rα)
+  (IH : Π a₁ b₁, (Π a₂ b₂, sym2.game_add rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+  game_add.fix hr IH a b = IH a b (λ a' b' h, game_add.fix hr IH a' b') :=
+well_founded.fix_eq _ _ _
+
+/-- Induction on the well-founded `sym2.game_add` relation. -/
+lemma game_add.induction {C : α → α → Prop} : well_founded rα →
+  (∀ a₁ b₁, (∀ a₂ b₂, sym2.game_add rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) → ∀ a b, C a b :=
+game_add.fix
+
+end sym2

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

feat(order/game_add): add more lemmas (#16082)

This PR does the following

  • add miscellaneous lemmas on prod.game_add
  • add a two-variable recursion principle for prod.game_add

Mathlib4 pair: https://github.com/leanprover-community/mathlib4/pull/1825

Diff
@@ -25,7 +25,6 @@ subsequency relation on the addition of combinatorial games.
 
 ## Todo
 
-- Add custom `induction` and `fix` lemmas.
 - Define `sym2.game_add`.
 -/
 
@@ -45,12 +44,31 @@ inductive game_add : α × β → α × β → Prop
 | fst {a₁ a₂ b} : rα a₁ a₂ → game_add (a₁, b) (a₂, b)
 | snd {a b₁ b₂} : rβ b₁ b₂ → game_add (a, b₁) (a, b₂)
 
-/-- `game_add` is a `subrelation` of `prod.lex`. -/
+lemma game_add_iff {rα rβ} {x y : α × β} :
+  game_add rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
+begin
+  split,
+  { rintro (@⟨a₁, a₂, b, h⟩ | @⟨a, b₁, b₂, h⟩),
+    exacts [or.inl ⟨h, rfl⟩, or.inr ⟨h, rfl⟩] },
+  { revert x y,
+    rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ (⟨h, rfl : b₁ = b₂⟩ | ⟨h, rfl : a₁ = a₂⟩),
+    exacts [game_add.fst h, game_add.snd h] }
+end
+
+lemma game_add_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
+  game_add rα rβ (a₁, b₁) (a₂, b₂) ↔ rα a₁ a₂ ∧ b₁ = b₂ ∨ rβ b₁ b₂ ∧ a₁ = a₂ :=
+game_add_iff
+
+@[simp] lemma game_add_swap_swap : ∀ a b : α × β,
+  game_add rβ rα a.swap b.swap ↔ game_add rα rβ a b :=
+λ ⟨a₁, b₁⟩ ⟨a₂, b₂⟩, by rw [prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm]
+
+/-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 lemma game_add_le_lex : game_add rα rβ ≤ prod.lex rα rβ :=
 λ _ _ h, h.rec (λ _ _ b, prod.lex.left b b) (λ a _ _, prod.lex.right a)
 
-/-- `prod.rprod` is a subrelation of the transitive closure of `game_add`. -/
-lemma rprod_le_trans_gen_game_add : prod.rprod rα rβ ≤ relation.trans_gen (game_add rα rβ) :=
+/-- `prod.rprod` is a subrelation of the transitive closure of `prod.game_add`. -/
+lemma rprod_le_trans_gen_game_add : rprod rα rβ ≤ relation.trans_gen (game_add rα rβ) :=
 λ _ _ h, h.rec begin
   intros _ _ _ _ hα hβ,
   exact relation.trans_gen.tail (relation.trans_gen.single $ game_add.fst hα) (game_add.snd hβ),
@@ -77,3 +95,28 @@ end
   In particular, the sum of two well-founded games is well-founded. -/
 lemma well_founded.prod_game_add (hα : well_founded rα) (hβ : well_founded rβ) :
   well_founded (prod.game_add rα rβ) := ⟨λ ⟨a, b⟩, (hα.apply a).prod_game_add (hβ.apply b)⟩
+
+namespace prod
+
+/-- Recursion on the well-founded `prod.game_add` relation.
+
+  Note that it's strictly more general to recurse on the lexicographic order instead. -/
+def game_add.fix {C : α → β → Sort*} (hα : well_founded rα) (hβ : well_founded rβ)
+  (IH : Π a₁ b₁, (Π a₂ b₂, game_add rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
+  C a b :=
+@well_founded.fix (α × β) (λ x, C x.1 x.2) _ (hα.prod_game_add hβ)
+  (λ ⟨x₁, x₂⟩ IH', IH x₁ x₂ $ λ a' b', IH' ⟨a', b'⟩) ⟨a, b⟩
+
+lemma game_add.fix_eq {C : α → β → Sort*} (hα : well_founded rα) (hβ : well_founded rβ)
+  (IH : Π a₁ b₁, (Π a₂ b₂, game_add rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
+  game_add.fix hα hβ IH a b = IH a b (λ a' b' h, game_add.fix hα hβ IH a' b') :=
+by { rw [game_add.fix, well_founded.fix_eq], refl }
+
+/-- Induction on the well-founded `prod.game_add` relation.
+
+  Note that it's strictly more general to induct on the lexicographic order instead. -/
+lemma game_add.induction {C : α → β → Prop} : well_founded rα → well_founded rβ →
+  (∀ a₁ b₁, (∀ a₂ b₂, game_add rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) → ∀ a b, C a b :=
+game_add.fix
+
+end prod

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

doc(order/game_add): improve docstrings (#18269)

We add simpler descriptions for game_add and well_founded.prod_game_add, without removing previous references to combinatorial games.

Mathlib 4 pair: https://github.com/leanprover-community/mathlib4/pull/1798

Diff
@@ -33,14 +33,17 @@ variables {α β : Type*} (rα : α → α → Prop) (rβ : β → β → Prop)
 
 namespace prod
 
-/-- The "addition of games" relation in combinatorial game theory, on the product type: if
-  `rα a' a` means that `a ⟶ a'` is a valid move in game `α`, and `rβ b' b` means that `b ⟶ b'`
-  is a valid move in game `β`, then `game_add rα rβ` specifies the valid moves in the juxtaposition
-  of `α` and `β`: the player is free to choose one of the games and make a move in it,
-  while leaving the other game unchanged. -/
+/-- `prod.game_add rα rβ x y` means that `x` can be reached from `y` by decreasing either entry with
+  respect to the relations `rα` and `rβ`.
+
+  It is so called, as it models game addition within combinatorial game theory. If `rα a₁ a₂` means
+  that `a₂ ⟶ a₁` is a valid move in game `α`, and `rβ b₁ b₂` means that `b₂ ⟶ b₁` is a valid move
+  in game `β`, then `game_add rα rβ` specifies the valid moves in the juxtaposition of `α` and `β`:
+  the player is free to choose one of the games and make a move in it, while leaving the other game
+  unchanged. -/
 inductive game_add : α × β → α × β → Prop
-| fst {a' a b} : rα a' a → game_add (a',b) (a,b)
-| snd {a b' b} : rβ b' b → game_add (a,b') (a,b)
+| fst {a₁ a₂ b} : rα a₁ a₂ → game_add (a₁, b) (a₂, b)
+| snd {a b₁ b₂} : rβ b₁ b₂ → game_add (a, b₁) (a, b₂)
 
 /-- `game_add` is a `subrelation` of `prod.lex`. -/
 lemma game_add_le_lex : game_add rα rβ ≤ prod.lex rα rβ :=
@@ -69,6 +72,8 @@ begin
   exacts [iha _ ra (acc.intro b hb), ihb _ rb],
 end
 
-/-- The sum of two well-founded games is well-founded. -/
+/-- The `prod.game_add` relation on well-founded inputs is well-founded.
+
+  In particular, the sum of two well-founded games is well-founded. -/
 lemma well_founded.prod_game_add (hα : well_founded rα) (hβ : well_founded rβ) :
-  well_founded (prod.game_add rα rβ) := ⟨λ ⟨a,b⟩, (hα.apply a).prod_game_add (hβ.apply b)⟩
+  well_founded (prod.game_add rα rβ) := ⟨λ ⟨a, b⟩, (hα.apply a).prod_game_add (hβ.apply b)⟩

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(no changes)

(first ported)

Changes in mathlib3port

mathlib3
mathlib3port
Diff
@@ -82,7 +82,7 @@ theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
 #print Prod.gameAdd_swap_swap /-
 @[simp]
 theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.symm b.symm ↔ GameAdd rα rβ a b :=
-  fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm']
+  fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm]
 #align prod.game_add_swap_swap Prod.gameAdd_swap_swap
 -/
 
@@ -188,7 +188,7 @@ def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
       fun a₁ b₁ a₂ b₂ =>
       by
       rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
-      simp [or_comm']⟩
+      simp [or_comm]⟩
 #align sym2.game_add Sym2.GameAdd
 -/
 
Diff
@@ -3,8 +3,8 @@ Copyright (c) 2022 Junyan Xu. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 -/
-import Mathbin.Data.Sym.Sym2
-import Mathbin.Logic.Relation
+import Data.Sym.Sym2
+import Logic.Relation
 
 #align_import order.game_add from "leanprover-community/mathlib"@"fee218fb033b2fd390c447f8be27754bc9093be9"
 
Diff
@@ -2,15 +2,12 @@
 Copyright (c) 2022 Junyan Xu. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
-
-! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit fee218fb033b2fd390c447f8be27754bc9093be9
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathbin.Data.Sym.Sym2
 import Mathbin.Logic.Relation
 
+#align_import order.game_add from "leanprover-community/mathlib"@"fee218fb033b2fd390c447f8be27754bc9093be9"
+
 /-!
 # Game addition relation
 
Diff
@@ -62,6 +62,7 @@ inductive GameAdd : α × β → α × β → Prop
 #align prod.game_add Prod.GameAdd
 -/
 
+#print Prod.gameAdd_iff /-
 theorem gameAdd_iff {rα rβ} {x y : α × β} :
     GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
   by
@@ -72,27 +73,37 @@ theorem gameAdd_iff {rα rβ} {x y : α × β} :
     rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ (⟨h, rfl : b₁ = b₂⟩ | ⟨h, rfl : a₁ = a₂⟩)
     exacts [game_add.fst h, game_add.snd h]
 #align prod.game_add_iff Prod.gameAdd_iff
+-/
 
+#print Prod.gameAdd_mk_iff /-
 theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ rα a₁ a₂ ∧ b₁ = b₂ ∨ rβ b₁ b₂ ∧ a₁ = a₂ :=
   gameAdd_iff
 #align prod.game_add_mk_iff Prod.gameAdd_mk_iff
+-/
 
+#print Prod.gameAdd_swap_swap /-
 @[simp]
 theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.symm b.symm ↔ GameAdd rα rβ a b :=
   fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm']
 #align prod.game_add_swap_swap Prod.gameAdd_swap_swap
+-/
 
+#print Prod.gameAdd_swap_swap_mk /-
 theorem gameAdd_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ GameAdd rβ rα (b₁, a₁) (b₂, a₂) :=
   gameAdd_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
 #align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mk
+-/
 
+#print Prod.gameAdd_le_lex /-
 /-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
   h.rec (fun _ _ b => Prod.Lex.left b b) fun a _ _ => Prod.Lex.right a
 #align prod.game_add_le_lex Prod.gameAdd_le_lex
+-/
 
+#print Prod.rprod_le_transGen_gameAdd /-
 /-- `prod.rprod` is a subrelation of the transitive closure of `prod.game_add`. -/
 theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ) := fun _ _ h =>
   h.rec
@@ -100,9 +111,11 @@ theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd
       intro _ _ _ _ hα hβ
       exact Relation.TransGen.tail (Relation.TransGen.single <| game_add.fst hα) (game_add.snd hβ))
 #align prod.rprod_le_trans_gen_game_add Prod.rprod_le_transGen_gameAdd
+-/
 
 end Prod
 
+#print Acc.prod_gameAdd /-
 /-- If `a` is accessible under `rα` and `b` is accessible under `rβ`, then `(a, b)` is
   accessible under `prod.game_add rα rβ`. Notice that `prod.lex_accessible` requires the
   stronger condition `∀ b, acc rβ b`. -/
@@ -114,7 +127,9 @@ theorem Acc.prod_gameAdd {a b} (ha : Acc rα a) (hb : Acc rβ b) : Acc (Prod.Gam
   rintro (⟨ra⟩ | ⟨rb⟩)
   exacts [iha _ ra (Acc.intro b hb), ihb _ rb]
 #align acc.prod_game_add Acc.prod_gameAdd
+-/
 
+#print WellFounded.prod_gameAdd /-
 /-- The `prod.game_add` relation on well-founded inputs is well-founded.
 
   In particular, the sum of two well-founded games is well-founded. -/
@@ -122,6 +137,7 @@ theorem WellFounded.prod_gameAdd (hα : WellFounded rα) (hβ : WellFounded rβ)
     WellFounded (Prod.GameAdd rα rβ) :=
   ⟨fun ⟨a, b⟩ => (hα.apply a).prod_gameAdd (hβ.apply b)⟩
 #align well_founded.prod_game_add WellFounded.prod_gameAdd
+-/
 
 namespace Prod
 
@@ -137,12 +153,15 @@ def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFo
 #align prod.game_add.fix Prod.GameAdd.fix
 -/
 
+#print Prod.GameAdd.fix_eq /-
 theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     GameAdd.fix hα hβ IH a b = IH a b fun a' b' h => GameAdd.fix hα hβ IH a' b' :=
   WellFounded.fix_eq _ _ _
 #align prod.game_add.fix_eq Prod.GameAdd.fix_eq
+-/
 
+#print Prod.GameAdd.induction /-
 /-- Induction on the well-founded `prod.game_add` relation.
 
   Note that it's strictly more general to induct on the lexicographic order instead. -/
@@ -152,6 +171,7 @@ theorem GameAdd.induction {C : α → β → Prop} :
         (∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) → ∀ a b, C a b :=
   GameAdd.fix
 #align prod.game_add.induction Prod.GameAdd.induction
+-/
 
 end Prod
 
Diff
@@ -67,10 +67,10 @@ theorem gameAdd_iff {rα rβ} {x y : α × β} :
   by
   constructor
   · rintro (@⟨a₁, a₂, b, h⟩ | @⟨a, b₁, b₂, h⟩)
-    exacts[Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
+    exacts [Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
   · revert x y
     rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ (⟨h, rfl : b₁ = b₂⟩ | ⟨h, rfl : a₁ = a₂⟩)
-    exacts[game_add.fst h, game_add.snd h]
+    exacts [game_add.fst h, game_add.snd h]
 #align prod.game_add_iff Prod.gameAdd_iff
 
 theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
@@ -112,7 +112,7 @@ theorem Acc.prod_gameAdd {a b} (ha : Acc rα a) (hb : Acc rβ b) : Acc (Prod.Gam
   induction' hb with b hb ihb
   refine' Acc.intro _ fun h => _
   rintro (⟨ra⟩ | ⟨rb⟩)
-  exacts[iha _ ra (Acc.intro b hb), ihb _ rb]
+  exacts [iha _ ra (Acc.intro b hb), ihb _ rb]
 #align acc.prod_game_add Acc.prod_gameAdd
 
 /-- The `prod.game_add` relation on well-founded inputs is well-founded.
Diff
@@ -62,12 +62,6 @@ inductive GameAdd : α × β → α × β → Prop
 #align prod.game_add Prod.GameAdd
 -/
 
-/- warning: prod.game_add_iff -> Prod.gameAdd_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {x : Prod.{u1, u2} α β} {y : Prod.{u1, u2} α β}, Iff (Prod.GameAdd.{u1, u2} α β rα rβ x y) (Or (And (rα (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y)) (Eq.{succ u2} β (Prod.snd.{u1, u2} α β x) (Prod.snd.{u1, u2} α β y))) (And (rβ (Prod.snd.{u1, u2} α β x) (Prod.snd.{u1, u2} α β y)) (Eq.{succ u1} α (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y))))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {x : Prod.{u2, u1} α β} {y : Prod.{u2, u1} α β}, Iff (Prod.GameAdd.{u2, u1} α β rα rβ x y) (Or (And (rα (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y)) (Eq.{succ u1} β (Prod.snd.{u2, u1} α β x) (Prod.snd.{u2, u1} α β y))) (And (rβ (Prod.snd.{u2, u1} α β x) (Prod.snd.{u2, u1} α β y)) (Eq.{succ u2} α (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y))))
-Case conversion may be inaccurate. Consider using '#align prod.game_add_iff Prod.gameAdd_iffₓ'. -/
 theorem gameAdd_iff {rα rβ} {x y : α × β} :
     GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
   by
@@ -79,56 +73,26 @@ theorem gameAdd_iff {rα rβ} {x y : α × β} :
     exacts[game_add.fst h, game_add.snd h]
 #align prod.game_add_iff Prod.gameAdd_iff
 
-/- warning: prod.game_add_mk_iff -> Prod.gameAdd_mk_iff is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₁ b₁) (Prod.mk.{u1, u2} α β a₂ b₂)) (Or (And (rα a₁ a₂) (Eq.{succ u2} β b₁ b₂)) (And (rβ b₁ b₂) (Eq.{succ u1} α a₁ a₂)))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₁ b₁) (Prod.mk.{u2, u1} α β a₂ b₂)) (Or (And (rα a₁ a₂) (Eq.{succ u1} β b₁ b₂)) (And (rβ b₁ b₂) (Eq.{succ u2} α a₁ a₂)))
-Case conversion may be inaccurate. Consider using '#align prod.game_add_mk_iff Prod.gameAdd_mk_iffₓ'. -/
 theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ rα a₁ a₂ ∧ b₁ = b₂ ∨ rβ b₁ b₂ ∧ a₁ = a₂ :=
   gameAdd_iff
 #align prod.game_add_mk_iff Prod.gameAdd_mk_iff
 
-/- warning: prod.game_add_swap_swap -> Prod.gameAdd_swap_swap is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β), Iff (Prod.GameAdd.{u2, u1} β α rβ rα (Prod.swap.{u1, u2} α β a) (Prod.swap.{u1, u2} α β b)) (Prod.GameAdd.{u1, u2} α β rα rβ a b)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β), Iff (Prod.GameAdd.{u1, u2} β α rβ rα (Prod.swap.{u2, u1} α β a) (Prod.swap.{u2, u1} α β b)) (Prod.GameAdd.{u2, u1} α β rα rβ a b)
-Case conversion may be inaccurate. Consider using '#align prod.game_add_swap_swap Prod.gameAdd_swap_swapₓ'. -/
 @[simp]
 theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.symm b.symm ↔ GameAdd rα rβ a b :=
   fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm']
 #align prod.game_add_swap_swap Prod.gameAdd_swap_swap
 
-/- warning: prod.game_add_swap_swap_mk -> Prod.gameAdd_swap_swap_mk is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a₁ : α) (a₂ : α) (b₁ : β) (b₂ : β), Iff (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₁ b₁) (Prod.mk.{u1, u2} α β a₂ b₂)) (Prod.GameAdd.{u2, u1} β α rβ rα (Prod.mk.{u2, u1} β α b₁ a₁) (Prod.mk.{u2, u1} β α b₂ a₂))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a₁ : α) (a₂ : α) (b₁ : β) (b₂ : β), Iff (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₁ b₁) (Prod.mk.{u2, u1} α β a₂ b₂)) (Prod.GameAdd.{u1, u2} β α rβ rα (Prod.mk.{u1, u2} β α b₁ a₁) (Prod.mk.{u1, u2} β α b₂ a₂))
-Case conversion may be inaccurate. Consider using '#align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mkₓ'. -/
 theorem gameAdd_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ GameAdd rβ rα (b₁, a₁) (b₂, a₂) :=
   gameAdd_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
 #align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mk
 
-/- warning: prod.game_add_le_lex -> Prod.gameAdd_le_lex is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u1 u2} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β) -> Prop) (Pi.hasLe.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => (Prod.{u1, u2} α β) -> Prop) (fun (i : Prod.{u1, u2} α β) => Pi.hasLe.{max u1 u2, 0} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => Prop) (fun (i : Prod.{u1, u2} α β) => Prop.le))) (Prod.GameAdd.{u1, u2} α β rα rβ) (Prod.Lex.{u1, u2} α β rα rβ)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u2 u1} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β) -> Prop) (Pi.hasLe.{max u2 u1, max u2 u1} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => (Prod.{u2, u1} α β) -> Prop) (fun (i : Prod.{u2, u1} α β) => Pi.hasLe.{max u2 u1, 0} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => Prop) (fun (i : Prod.{u2, u1} α β) => Prop.le))) (Prod.GameAdd.{u2, u1} α β rα rβ) (Prod.Lex.{u2, u1} α β rα rβ)
-Case conversion may be inaccurate. Consider using '#align prod.game_add_le_lex Prod.gameAdd_le_lexₓ'. -/
 /-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
   h.rec (fun _ _ b => Prod.Lex.left b b) fun a _ _ => Prod.Lex.right a
 #align prod.game_add_le_lex Prod.gameAdd_le_lex
 
-/- warning: prod.rprod_le_trans_gen_game_add -> Prod.rprod_le_transGen_gameAdd is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u1 u2} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β) -> Prop) (Pi.hasLe.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => (Prod.{u1, u2} α β) -> Prop) (fun (i : Prod.{u1, u2} α β) => Pi.hasLe.{max u1 u2, 0} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => Prop) (fun (i : Prod.{u1, u2} α β) => Prop.le))) (Prod.RProd.{u1, u2} α β rα rβ) (Relation.TransGen.{max u1 u2} (Prod.{u1, u2} α β) (Prod.GameAdd.{u1, u2} α β rα rβ))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u2 u1} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β) -> Prop) (Pi.hasLe.{max u2 u1, max u2 u1} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => (Prod.{u2, u1} α β) -> Prop) (fun (i : Prod.{u2, u1} α β) => Pi.hasLe.{max u2 u1, 0} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => Prop) (fun (i : Prod.{u2, u1} α β) => Prop.le))) (Prod.RProd.{u2, u1} α β rα rβ) (Relation.TransGen.{max u1 u2} (Prod.{u2, u1} α β) (Prod.GameAdd.{u2, u1} α β rα rβ))
-Case conversion may be inaccurate. Consider using '#align prod.rprod_le_trans_gen_game_add Prod.rprod_le_transGen_gameAddₓ'. -/
 /-- `prod.rprod` is a subrelation of the transitive closure of `prod.game_add`. -/
 theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ) := fun _ _ h =>
   h.rec
@@ -139,12 +103,6 @@ theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd
 
 end Prod
 
-/- warning: acc.prod_game_add -> Acc.prod_gameAdd is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a : α} {b : β}, (Acc.{succ u1} α rα a) -> (Acc.{succ u2} β rβ b) -> (Acc.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.GameAdd.{u1, u2} α β rα rβ) (Prod.mk.{u1, u2} α β a b))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a : α} {b : β}, (Acc.{succ u2} α rα a) -> (Acc.{succ u1} β rβ b) -> (Acc.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) (Prod.GameAdd.{u2, u1} α β rα rβ) (Prod.mk.{u2, u1} α β a b))
-Case conversion may be inaccurate. Consider using '#align acc.prod_game_add Acc.prod_gameAddₓ'. -/
 /-- If `a` is accessible under `rα` and `b` is accessible under `rβ`, then `(a, b)` is
   accessible under `prod.game_add rα rβ`. Notice that `prod.lex_accessible` requires the
   stronger condition `∀ b, acc rβ b`. -/
@@ -157,12 +115,6 @@ theorem Acc.prod_gameAdd {a b} (ha : Acc rα a) (hb : Acc rβ b) : Acc (Prod.Gam
   exacts[iha _ ra (Acc.intro b hb), ihb _ rb]
 #align acc.prod_game_add Acc.prod_gameAdd
 
-/- warning: well_founded.prod_game_add -> WellFounded.prod_gameAdd is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop}, (WellFounded.{succ u1} α rα) -> (WellFounded.{succ u2} β rβ) -> (WellFounded.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.GameAdd.{u1, u2} α β rα rβ))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop}, (WellFounded.{succ u2} α rα) -> (WellFounded.{succ u1} β rβ) -> (WellFounded.{max (succ u1) (succ u2)} (Prod.{u2, u1} α β) (Prod.GameAdd.{u2, u1} α β rα rβ))
-Case conversion may be inaccurate. Consider using '#align well_founded.prod_game_add WellFounded.prod_gameAddₓ'. -/
 /-- The `prod.game_add` relation on well-founded inputs is well-founded.
 
   In particular, the sum of two well-founded games is well-founded. -/
@@ -185,24 +137,12 @@ def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFo
 #align prod.game_add.fix Prod.GameAdd.fix
 -/
 
-/- warning: prod.game_add.fix_eq -> Prod.GameAdd.fix_eq is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Sort.{u3}} (hα : WellFounded.{succ u1} α rα) (hβ : WellFounded.{succ u2} β rβ) (IH : forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₂ b₂) (Prod.mk.{u1, u2} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) (a : α) (b : β), Eq.{u3} (C a b) (Prod.GameAdd.fix.{u1, u2, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a b) (IH a b (fun (a' : α) (b' : β) (h : Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a' b') (Prod.mk.{u1, u2} α β a b)) => Prod.GameAdd.fix.{u1, u2, u3} α β rα rβ C hα hβ IH a' b'))
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Sort.{u3}} (hα : WellFounded.{succ u2} α rα) (hβ : WellFounded.{succ u1} β rβ) (IH : forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₂ b₂) (Prod.mk.{u2, u1} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) (a : α) (b : β), Eq.{u3} (C a b) (Prod.GameAdd.fix.{u2, u1, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a b) (IH a b (fun (a' : α) (b' : β) (h : Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a' b') (Prod.mk.{u2, u1} α β a b)) => Prod.GameAdd.fix.{u2, u1, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a' b'))
-Case conversion may be inaccurate. Consider using '#align prod.game_add.fix_eq Prod.GameAdd.fix_eqₓ'. -/
 theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     GameAdd.fix hα hβ IH a b = IH a b fun a' b' h => GameAdd.fix hα hβ IH a' b' :=
   WellFounded.fix_eq _ _ _
 #align prod.game_add.fix_eq Prod.GameAdd.fix_eq
 
-/- warning: prod.game_add.induction -> Prod.GameAdd.induction is a dubious translation:
-lean 3 declaration is
-  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Prop}, (WellFounded.{succ u1} α rα) -> (WellFounded.{succ u2} β rβ) -> (forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₂ b₂) (Prod.mk.{u1, u2} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) -> (forall (a : α) (b : β), C a b)
-but is expected to have type
-  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Prop}, (WellFounded.{succ u2} α rα) -> (WellFounded.{succ u1} β rβ) -> (forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₂ b₂) (Prod.mk.{u2, u1} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) -> (forall (a : α) (b : β), C a b)
-Case conversion may be inaccurate. Consider using '#align prod.game_add.induction Prod.GameAdd.inductionₓ'. -/
 /-- Induction on the well-founded `prod.game_add` relation.
 
   Note that it's strictly more general to induct on the lexicographic order instead. -/
Diff
@@ -239,10 +239,8 @@ variable {rα}
 
 #print Sym2.gameAdd_iff /-
 theorem gameAdd_iff :
-    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.symm y :=
-  by
-  rintro ⟨_, _⟩ ⟨_, _⟩
-  rfl
+    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.symm y := by
+  rintro ⟨_, _⟩ ⟨_, _⟩; rfl
 #align sym2.game_add_iff Sym2.gameAdd_iff
 -/
 
@@ -274,18 +272,14 @@ theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a,
 -/
 
 #print Sym2.GameAdd.fst_snd /-
-theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
-  by
-  rw [Sym2.eq_swap]
-  exact game_add.snd h
+theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ := by
+  rw [Sym2.eq_swap]; exact game_add.snd h
 #align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
 -/
 
 #print Sym2.GameAdd.snd_fst /-
-theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
-  by
-  rw [Sym2.eq_swap]
-  exact game_add.fst h
+theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ := by
+  rw [Sym2.eq_swap]; exact game_add.fst h
 #align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
 -/
 
Diff
@@ -62,6 +62,12 @@ inductive GameAdd : α × β → α × β → Prop
 #align prod.game_add Prod.GameAdd
 -/
 
+/- warning: prod.game_add_iff -> Prod.gameAdd_iff is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {x : Prod.{u1, u2} α β} {y : Prod.{u1, u2} α β}, Iff (Prod.GameAdd.{u1, u2} α β rα rβ x y) (Or (And (rα (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y)) (Eq.{succ u2} β (Prod.snd.{u1, u2} α β x) (Prod.snd.{u1, u2} α β y))) (And (rβ (Prod.snd.{u1, u2} α β x) (Prod.snd.{u1, u2} α β y)) (Eq.{succ u1} α (Prod.fst.{u1, u2} α β x) (Prod.fst.{u1, u2} α β y))))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {x : Prod.{u2, u1} α β} {y : Prod.{u2, u1} α β}, Iff (Prod.GameAdd.{u2, u1} α β rα rβ x y) (Or (And (rα (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y)) (Eq.{succ u1} β (Prod.snd.{u2, u1} α β x) (Prod.snd.{u2, u1} α β y))) (And (rβ (Prod.snd.{u2, u1} α β x) (Prod.snd.{u2, u1} α β y)) (Eq.{succ u2} α (Prod.fst.{u2, u1} α β x) (Prod.fst.{u2, u1} α β y))))
+Case conversion may be inaccurate. Consider using '#align prod.game_add_iff Prod.gameAdd_iffₓ'. -/
 theorem gameAdd_iff {rα rβ} {x y : α × β} :
     GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
   by
@@ -73,29 +79,56 @@ theorem gameAdd_iff {rα rβ} {x y : α × β} :
     exacts[game_add.fst h, game_add.snd h]
 #align prod.game_add_iff Prod.gameAdd_iff
 
+/- warning: prod.game_add_mk_iff -> Prod.gameAdd_mk_iff is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₁ b₁) (Prod.mk.{u1, u2} α β a₂ b₂)) (Or (And (rα a₁ a₂) (Eq.{succ u2} β b₁ b₂)) (And (rβ b₁ b₂) (Eq.{succ u1} α a₁ a₂)))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a₁ : α} {a₂ : α} {b₁ : β} {b₂ : β}, Iff (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₁ b₁) (Prod.mk.{u2, u1} α β a₂ b₂)) (Or (And (rα a₁ a₂) (Eq.{succ u1} β b₁ b₂)) (And (rβ b₁ b₂) (Eq.{succ u2} α a₁ a₂)))
+Case conversion may be inaccurate. Consider using '#align prod.game_add_mk_iff Prod.gameAdd_mk_iffₓ'. -/
 theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ rα a₁ a₂ ∧ b₁ = b₂ ∨ rβ b₁ b₂ ∧ a₁ = a₂ :=
   gameAdd_iff
 #align prod.game_add_mk_iff Prod.gameAdd_mk_iff
 
+/- warning: prod.game_add_swap_swap -> Prod.gameAdd_swap_swap is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a : Prod.{u1, u2} α β) (b : Prod.{u1, u2} α β), Iff (Prod.GameAdd.{u2, u1} β α rβ rα (Prod.swap.{u1, u2} α β a) (Prod.swap.{u1, u2} α β b)) (Prod.GameAdd.{u1, u2} α β rα rβ a b)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a : Prod.{u2, u1} α β) (b : Prod.{u2, u1} α β), Iff (Prod.GameAdd.{u1, u2} β α rβ rα (Prod.swap.{u2, u1} α β a) (Prod.swap.{u2, u1} α β b)) (Prod.GameAdd.{u2, u1} α β rα rβ a b)
+Case conversion may be inaccurate. Consider using '#align prod.game_add_swap_swap Prod.gameAdd_swap_swapₓ'. -/
 @[simp]
 theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.symm b.symm ↔ GameAdd rα rβ a b :=
   fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm']
 #align prod.game_add_swap_swap Prod.gameAdd_swap_swap
 
+/- warning: prod.game_add_swap_swap_mk -> Prod.gameAdd_swap_swap_mk is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a₁ : α) (a₂ : α) (b₁ : β) (b₂ : β), Iff (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₁ b₁) (Prod.mk.{u1, u2} α β a₂ b₂)) (Prod.GameAdd.{u2, u1} β α rβ rα (Prod.mk.{u2, u1} β α b₁ a₁) (Prod.mk.{u2, u1} β α b₂ a₂))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop) (a₁ : α) (a₂ : α) (b₁ : β) (b₂ : β), Iff (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₁ b₁) (Prod.mk.{u2, u1} α β a₂ b₂)) (Prod.GameAdd.{u1, u2} β α rβ rα (Prod.mk.{u1, u2} β α b₁ a₁) (Prod.mk.{u1, u2} β α b₂ a₂))
+Case conversion may be inaccurate. Consider using '#align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mkₓ'. -/
 theorem gameAdd_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
     GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ GameAdd rβ rα (b₁, a₁) (b₂, a₂) :=
   gameAdd_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
 #align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mk
 
-#print Prod.gameAdd_le_lex /-
+/- warning: prod.game_add_le_lex -> Prod.gameAdd_le_lex is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u1 u2} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β) -> Prop) (Pi.hasLe.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => (Prod.{u1, u2} α β) -> Prop) (fun (i : Prod.{u1, u2} α β) => Pi.hasLe.{max u1 u2, 0} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => Prop) (fun (i : Prod.{u1, u2} α β) => Prop.le))) (Prod.GameAdd.{u1, u2} α β rα rβ) (Prod.Lex.{u1, u2} α β rα rβ)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u2 u1} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β) -> Prop) (Pi.hasLe.{max u2 u1, max u2 u1} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => (Prod.{u2, u1} α β) -> Prop) (fun (i : Prod.{u2, u1} α β) => Pi.hasLe.{max u2 u1, 0} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => Prop) (fun (i : Prod.{u2, u1} α β) => Prop.le))) (Prod.GameAdd.{u2, u1} α β rα rβ) (Prod.Lex.{u2, u1} α β rα rβ)
+Case conversion may be inaccurate. Consider using '#align prod.game_add_le_lex Prod.gameAdd_le_lexₓ'. -/
 /-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
   h.rec (fun _ _ b => Prod.Lex.left b b) fun a _ _ => Prod.Lex.right a
 #align prod.game_add_le_lex Prod.gameAdd_le_lex
--/
 
-#print Prod.rprod_le_transGen_gameAdd /-
+/- warning: prod.rprod_le_trans_gen_game_add -> Prod.rprod_le_transGen_gameAdd is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u1 u2} ((Prod.{u1, u2} α β) -> (Prod.{u1, u2} α β) -> Prop) (Pi.hasLe.{max u1 u2, max u1 u2} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => (Prod.{u1, u2} α β) -> Prop) (fun (i : Prod.{u1, u2} α β) => Pi.hasLe.{max u1 u2, 0} (Prod.{u1, u2} α β) (fun (ᾰ : Prod.{u1, u2} α β) => Prop) (fun (i : Prod.{u1, u2} α β) => Prop.le))) (Prod.RProd.{u1, u2} α β rα rβ) (Relation.TransGen.{max u1 u2} (Prod.{u1, u2} α β) (Prod.GameAdd.{u1, u2} α β rα rβ))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} (rα : α -> α -> Prop) (rβ : β -> β -> Prop), LE.le.{max u2 u1} ((Prod.{u2, u1} α β) -> (Prod.{u2, u1} α β) -> Prop) (Pi.hasLe.{max u2 u1, max u2 u1} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => (Prod.{u2, u1} α β) -> Prop) (fun (i : Prod.{u2, u1} α β) => Pi.hasLe.{max u2 u1, 0} (Prod.{u2, u1} α β) (fun (ᾰ : Prod.{u2, u1} α β) => Prop) (fun (i : Prod.{u2, u1} α β) => Prop.le))) (Prod.RProd.{u2, u1} α β rα rβ) (Relation.TransGen.{max u1 u2} (Prod.{u2, u1} α β) (Prod.GameAdd.{u2, u1} α β rα rβ))
+Case conversion may be inaccurate. Consider using '#align prod.rprod_le_trans_gen_game_add Prod.rprod_le_transGen_gameAddₓ'. -/
 /-- `prod.rprod` is a subrelation of the transitive closure of `prod.game_add`. -/
 theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ) := fun _ _ h =>
   h.rec
@@ -103,7 +136,6 @@ theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd
       intro _ _ _ _ hα hβ
       exact Relation.TransGen.tail (Relation.TransGen.single <| game_add.fst hα) (game_add.snd hβ))
 #align prod.rprod_le_trans_gen_game_add Prod.rprod_le_transGen_gameAdd
--/
 
 end Prod
 
@@ -141,6 +173,7 @@ theorem WellFounded.prod_gameAdd (hα : WellFounded rα) (hβ : WellFounded rβ)
 
 namespace Prod
 
+#print Prod.GameAdd.fix /-
 /-- Recursion on the well-founded `prod.game_add` relation.
 
   Note that it's strictly more general to recurse on the lexicographic order instead. -/
@@ -150,13 +183,26 @@ def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFo
   @WellFounded.fix (α × β) (fun x => C x.1 x.2) _ (hα.prod_gameAdd hβ)
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) ⟨a, b⟩
 #align prod.game_add.fix Prod.GameAdd.fix
+-/
 
+/- warning: prod.game_add.fix_eq -> Prod.GameAdd.fix_eq is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Sort.{u3}} (hα : WellFounded.{succ u1} α rα) (hβ : WellFounded.{succ u2} β rβ) (IH : forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₂ b₂) (Prod.mk.{u1, u2} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) (a : α) (b : β), Eq.{u3} (C a b) (Prod.GameAdd.fix.{u1, u2, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a b) (IH a b (fun (a' : α) (b' : β) (h : Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a' b') (Prod.mk.{u1, u2} α β a b)) => Prod.GameAdd.fix.{u1, u2, u3} α β rα rβ C hα hβ IH a' b'))
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Sort.{u3}} (hα : WellFounded.{succ u2} α rα) (hβ : WellFounded.{succ u1} β rβ) (IH : forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₂ b₂) (Prod.mk.{u2, u1} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) (a : α) (b : β), Eq.{u3} (C a b) (Prod.GameAdd.fix.{u2, u1, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a b) (IH a b (fun (a' : α) (b' : β) (h : Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a' b') (Prod.mk.{u2, u1} α β a b)) => Prod.GameAdd.fix.{u2, u1, u3} α β rα rβ (fun (a₂ : α) (b₂ : β) => C a₂ b₂) hα hβ IH a' b'))
+Case conversion may be inaccurate. Consider using '#align prod.game_add.fix_eq Prod.GameAdd.fix_eqₓ'. -/
 theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     GameAdd.fix hα hβ IH a b = IH a b fun a' b' h => GameAdd.fix hα hβ IH a' b' :=
   WellFounded.fix_eq _ _ _
 #align prod.game_add.fix_eq Prod.GameAdd.fix_eq
 
+/- warning: prod.game_add.induction -> Prod.GameAdd.induction is a dubious translation:
+lean 3 declaration is
+  forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Prop}, (WellFounded.{succ u1} α rα) -> (WellFounded.{succ u2} β rβ) -> (forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u1, u2} α β rα rβ (Prod.mk.{u1, u2} α β a₂ b₂) (Prod.mk.{u1, u2} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) -> (forall (a : α) (b : β), C a b)
+but is expected to have type
+  forall {α : Type.{u2}} {β : Type.{u1}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {C : α -> β -> Prop}, (WellFounded.{succ u2} α rα) -> (WellFounded.{succ u1} β rβ) -> (forall (a₁ : α) (b₁ : β), (forall (a₂ : α) (b₂ : β), (Prod.GameAdd.{u2, u1} α β rα rβ (Prod.mk.{u2, u1} α β a₂ b₂) (Prod.mk.{u2, u1} α β a₁ b₁)) -> (C a₂ b₂)) -> (C a₁ b₁)) -> (forall (a : α) (b : β), C a b)
+Case conversion may be inaccurate. Consider using '#align prod.game_add.induction Prod.GameAdd.inductionₓ'. -/
 /-- Induction on the well-founded `prod.game_add` relation.
 
   Note that it's strictly more general to induct on the lexicographic order instead. -/
@@ -174,6 +220,7 @@ end Prod
 
 namespace Sym2
 
+#print Sym2.GameAdd /-
 /-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry with
   respect to the relation `rα`.
 
@@ -186,49 +233,65 @@ def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
       rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
       simp [or_comm']⟩
 #align sym2.game_add Sym2.GameAdd
+-/
 
 variable {rα}
 
+#print Sym2.gameAdd_iff /-
 theorem gameAdd_iff :
     ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.symm y :=
   by
   rintro ⟨_, _⟩ ⟨_, _⟩
   rfl
 #align sym2.game_add_iff Sym2.gameAdd_iff
+-/
 
+#print Sym2.gameAdd_mk'_iff /-
 theorem gameAdd_mk'_iff {a₁ a₂ b₁ b₂ : α} :
     GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ ↔
       Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂) :=
   Iff.rfl
 #align sym2.game_add_mk_iff Sym2.gameAdd_mk'_iff
+-/
 
+#print Prod.GameAdd.to_sym2 /-
 theorem Prod.GameAdd.to_sym2 {a₁ a₂ b₁ b₂ : α} (h : Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂)) :
     Sym2.GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ :=
   gameAdd_mk'_iff.2 <| Or.inl <| h
 #align prod.game_add.to_sym2 Prod.GameAdd.to_sym2
+-/
 
+#print Sym2.GameAdd.fst /-
 theorem GameAdd.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(a₂, b)⟧ :=
   (Prod.GameAdd.fst h).to_sym2
 #align sym2.game_add.fst Sym2.GameAdd.fst
+-/
 
+#print Sym2.GameAdd.snd /-
 theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a, b₁)⟧ ⟦(a, b₂)⟧ :=
   (Prod.GameAdd.snd h).to_sym2
 #align sym2.game_add.snd Sym2.GameAdd.snd
+-/
 
+#print Sym2.GameAdd.fst_snd /-
 theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
   by
   rw [Sym2.eq_swap]
   exact game_add.snd h
 #align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
+-/
 
+#print Sym2.GameAdd.snd_fst /-
 theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
   by
   rw [Sym2.eq_swap]
   exact game_add.fst h
 #align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
+-/
 
 end Sym2
 
+#print Acc.sym2_gameAdd /-
 theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) : Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ :=
   by
   induction' ha with a ha iha generalizing b
@@ -243,14 +306,18 @@ theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) : Acc (Sym2.Gam
   · rw [Sym2.eq_swap]
     exact ihb c rc
 #align acc.sym2_game_add Acc.sym2_gameAdd
+-/
 
+#print WellFounded.sym2_gameAdd /-
 /-- The `sym2.game_add` relation on well-founded inputs is well-founded. -/
 theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameAdd rα) :=
   ⟨fun i => Sym2.inductionOn i fun x y => (h.apply x).sym2_gameAdd (h.apply y)⟩
 #align well_founded.sym2_game_add WellFounded.sym2_gameAdd
+-/
 
 namespace Sym2
 
+#print Sym2.GameAdd.fix /-
 /-- Recursion on the well-founded `sym2.game_add` relation. -/
 def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
@@ -258,13 +325,17 @@ def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
   @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ hr.sym2_gameAdd.of_quotient_lift₂
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
 #align sym2.game_add.fix Sym2.GameAdd.fix
+-/
 
+#print Sym2.GameAdd.fix_eq /-
 theorem GameAdd.fix_eq {C : α → α → Sort _} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
     GameAdd.fix hr IH a b = IH a b fun a' b' h => GameAdd.fix hr IH a' b' :=
   WellFounded.fix_eq _ _ _
 #align sym2.game_add.fix_eq Sym2.GameAdd.fix_eq
+-/
 
+#print Sym2.GameAdd.induction /-
 /-- Induction on the well-founded `sym2.game_add` relation. -/
 theorem GameAdd.induction {C : α → α → Prop} :
     WellFounded rα →
@@ -272,6 +343,7 @@ theorem GameAdd.induction {C : α → α → Prop} :
         ∀ a b, C a b :=
   GameAdd.fix
 #align sym2.game_add.induction Sym2.GameAdd.induction
+-/
 
 end Sym2
 
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 
 ! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit 7b1d4abc172ea1bcf200d11041d61a4fba058023
+! leanprover-community/mathlib commit fee218fb033b2fd390c447f8be27754bc9093be9
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
@@ -22,6 +22,8 @@ This file defines, given relations `rα : α → α → Prop` and `rβ : β →
 decreasing either entry (with respect to `rα` and `rβ`). It is so called since it models the
 subsequency relation on the addition of combinatorial games.
 
+We also define `sym2.game_add`, which is the unordered pair analog of `prod.game_add`.
+
 ## Main definitions and results
 
 - `prod.game_add`: the game addition relation on ordered pairs.
@@ -51,7 +53,9 @@ variable (rα rβ)
   that `a₂ ⟶ a₁` is a valid move in game `α`, and `rβ b₁ b₂` means that `b₂ ⟶ b₁` is a valid move
   in game `β`, then `game_add rα rβ` specifies the valid moves in the juxtaposition of `α` and `β`:
   the player is free to choose one of the games and make a move in it, while leaving the other game
-  unchanged. -/
+  unchanged.
+
+  See `sym2.game_add` for the unordered pair analog. -/
 inductive GameAdd : α × β → α × β → Prop
   | fst {a₁ a₂ b} : rα a₁ a₂ → game_add (a₁, b) (a₂, b)
   | snd {a b₁ b₂} : rβ b₁ b₂ → game_add (a, b₁) (a, b₂)
@@ -170,7 +174,10 @@ end Prod
 
 namespace Sym2
 
-/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry. -/
+/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry with
+  respect to the relation `rα`.
+
+  See `prod.game_add` for the ordered pair analog. -/
 def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
   Sym2.lift₂
     ⟨fun a₁ b₁ a₂ b₂ => Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂),
Diff
@@ -4,11 +4,11 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 
 ! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit 4d75632823d091877e5e63cc5694c8cb807cb7d4
+! leanprover-community/mathlib commit 7b1d4abc172ea1bcf200d11041d61a4fba058023
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
-import Mathbin.Order.Basic
+import Mathbin.Data.Sym.Sym2
 import Mathbin.Logic.Relation
 
 /-!
@@ -28,16 +28,21 @@ subsequency relation on the addition of combinatorial games.
 - `well_founded.prod_game_add`: formalizes induction on ordered pairs, where exactly one entry
   decreases at a time.
 
-## Todo
-
-- Define `sym2.game_add`.
+- `sym2.game_add`: the game addition relation on unordered pairs.
+- `well_founded.sym2_game_add`: formalizes induction on unordered pairs, where exactly one entry
+  decreases at a time.
 -/
 
 
-variable {α β : Type _} (rα : α → α → Prop) (rβ : β → β → Prop)
+variable {α β : Type _} {rα : α → α → Prop} {rβ : β → β → Prop}
+
+/-! ### `prod.game_add` -/
+
 
 namespace Prod
 
+variable (rα rβ)
+
 #print Prod.GameAdd /-
 /-- `prod.game_add rα rβ x y` means that `x` can be reached from `y` by decreasing either entry with
   respect to the relations `rα` and `rβ`.
@@ -74,6 +79,11 @@ theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.symm b.symm 
   fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, game_add_mk_iff, game_add_mk_iff, or_comm']
 #align prod.game_add_swap_swap Prod.gameAdd_swap_swap
 
+theorem gameAdd_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
+    GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ GameAdd rβ rα (b₁, a₁) (b₂, a₂) :=
+  gameAdd_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
+#align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mk
+
 #print Prod.gameAdd_le_lex /-
 /-- `prod.game_add` is a `subrelation` of `prod.lex`. -/
 theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
@@ -93,8 +103,6 @@ theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd
 
 end Prod
 
-variable {rα rβ}
-
 /- warning: acc.prod_game_add -> Acc.prod_gameAdd is a dubious translation:
 lean 3 declaration is
   forall {α : Type.{u1}} {β : Type.{u2}} {rα : α -> α -> Prop} {rβ : β -> β -> Prop} {a : α} {b : β}, (Acc.{succ u1} α rα a) -> (Acc.{succ u2} β rβ b) -> (Acc.{max (succ u1) (succ u2)} (Prod.{u1, u2} α β) (Prod.GameAdd.{u1, u2} α β rα rβ) (Prod.mk.{u1, u2} α β a b))
@@ -142,9 +150,7 @@ def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFo
 theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     GameAdd.fix hα hβ IH a b = IH a b fun a' b' h => GameAdd.fix hα hβ IH a' b' :=
-  by
-  rw [game_add.fix, WellFounded.fix_eq]
-  rfl
+  WellFounded.fix_eq _ _ _
 #align prod.game_add.fix_eq Prod.GameAdd.fix_eq
 
 /-- Induction on the well-founded `prod.game_add` relation.
@@ -159,3 +165,106 @@ theorem GameAdd.induction {C : α → β → Prop} :
 
 end Prod
 
+/-! ### `sym2.game_add` -/
+
+
+namespace Sym2
+
+/-- `sym2.game_add rα x y` means that `x` can be reached from `y` by decreasing either entry. -/
+def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
+  Sym2.lift₂
+    ⟨fun a₁ b₁ a₂ b₂ => Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂),
+      fun a₁ b₁ a₂ b₂ =>
+      by
+      rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
+      simp [or_comm']⟩
+#align sym2.game_add Sym2.GameAdd
+
+variable {rα}
+
+theorem gameAdd_iff :
+    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.symm y :=
+  by
+  rintro ⟨_, _⟩ ⟨_, _⟩
+  rfl
+#align sym2.game_add_iff Sym2.gameAdd_iff
+
+theorem gameAdd_mk'_iff {a₁ a₂ b₁ b₂ : α} :
+    GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ ↔
+      Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂) :=
+  Iff.rfl
+#align sym2.game_add_mk_iff Sym2.gameAdd_mk'_iff
+
+theorem Prod.GameAdd.to_sym2 {a₁ a₂ b₁ b₂ : α} (h : Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂)) :
+    Sym2.GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ :=
+  gameAdd_mk'_iff.2 <| Or.inl <| h
+#align prod.game_add.to_sym2 Prod.GameAdd.to_sym2
+
+theorem GameAdd.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(a₂, b)⟧ :=
+  (Prod.GameAdd.fst h).to_sym2
+#align sym2.game_add.fst Sym2.GameAdd.fst
+
+theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a, b₁)⟧ ⟦(a, b₂)⟧ :=
+  (Prod.GameAdd.snd h).to_sym2
+#align sym2.game_add.snd Sym2.GameAdd.snd
+
+theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
+  by
+  rw [Sym2.eq_swap]
+  exact game_add.snd h
+#align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
+
+theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
+  by
+  rw [Sym2.eq_swap]
+  exact game_add.fst h
+#align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
+
+end Sym2
+
+theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) : Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ :=
+  by
+  induction' ha with a ha iha generalizing b
+  induction' hb with b hb ihb
+  refine' Acc.intro _ fun s => _
+  induction' s using Sym2.inductionOn with c d
+  rintro ((rc | rd) | (rd | rc))
+  · exact iha c rc ⟨b, hb⟩
+  · exact ihb d rd
+  · rw [Sym2.eq_swap]
+    exact iha d rd ⟨b, hb⟩
+  · rw [Sym2.eq_swap]
+    exact ihb c rc
+#align acc.sym2_game_add Acc.sym2_gameAdd
+
+/-- The `sym2.game_add` relation on well-founded inputs is well-founded. -/
+theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameAdd rα) :=
+  ⟨fun i => Sym2.inductionOn i fun x y => (h.apply x).sym2_gameAdd (h.apply y)⟩
+#align well_founded.sym2_game_add WellFounded.sym2_gameAdd
+
+namespace Sym2
+
+/-- Recursion on the well-founded `sym2.game_add` relation. -/
+def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    C a b :=
+  @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ hr.sym2_gameAdd.of_quotient_lift₂
+    (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
+#align sym2.game_add.fix Sym2.GameAdd.fix
+
+theorem GameAdd.fix_eq {C : α → α → Sort _} (hr : WellFounded rα)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    GameAdd.fix hr IH a b = IH a b fun a' b' h => GameAdd.fix hr IH a' b' :=
+  WellFounded.fix_eq _ _ _
+#align sym2.game_add.fix_eq Sym2.GameAdd.fix_eq
+
+/-- Induction on the well-founded `sym2.game_add` relation. -/
+theorem GameAdd.induction {C : α → α → Prop} :
+    WellFounded rα →
+      (∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) →
+        ∀ a b, C a b :=
+  GameAdd.fix
+#align sym2.game_add.induction Sym2.GameAdd.induction
+
+end Sym2
+

Changes in mathlib4

mathlib3
mathlib4
chore(*): rename FunLike to DFunLike (#9785)

This prepares for the introduction of a non-dependent synonym of FunLike, which helps a lot with keeping #8386 readable.

This is entirely search-and-replace in 680197f combined with manual fixes in 4145626, e900597 and b8428f8. The commands that generated this change:

sed -i 's/\bFunLike\b/DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoFunLike\b/toDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/import Mathlib.Data.DFunLike/import Mathlib.Data.FunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bHom_FunLike\b/Hom_DFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean     
sed -i 's/\binstFunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\bfunLike\b/instDFunLike/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean
sed -i 's/\btoo many metavariables to apply `fun_like.has_coe_to_fun`/too many metavariables to apply `DFunLike.hasCoeToFun`/g' {Archive,Counterexamples,Mathlib,test}/**/*.lean

Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>

Diff
@@ -230,7 +230,7 @@ def GameAdd.fix {C : α → α → Sort*} (hr : WellFounded rα)
     C a b := by
   -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
   have := hr.sym2_gameAdd
-  dsimp only [GameAdd, lift₂, FunLike.coe, EquivLike.coe] at this
+  dsimp only [GameAdd, lift₂, DFunLike.coe, EquivLike.coe] at this
   exact @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ this.of_quotient_lift₂
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
 #align sym2.game_add.fix Sym2.GameAdd.fix
chore(*): replace $ with <| (#9319)

See Zulip thread for the discussion.

Diff
@@ -91,7 +91,7 @@ theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
 theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ)
   | _, _, h => h.rec (by
       intro _ _ _ _ hα hβ
-      exact Relation.TransGen.tail (Relation.TransGen.single $ GameAdd.fst hα) (GameAdd.snd hβ))
+      exact Relation.TransGen.tail (Relation.TransGen.single <| GameAdd.fst hα) (GameAdd.snd hβ))
 #align prod.rprod_le_trans_gen_game_add Prod.rprod_le_transGen_gameAdd
 
 end Prod
refactor: remove Sym2's global Prod setoid instance, use s(x, y) notation for unordered pairs (#8729)

The Sym2 type used a global setoid instance on α × α so that ⟦(x, y)⟧ could stand for an unordered pair using standard Quotient syntax. This commit refactors Sym2 to not use Quotient and instead use its own s(x, y) notation. One benefit to this is that this notation produces a term with type Sym2 rather than Quotient.

The Fintype instance for Sym2 is in Mathlib.Data.Finset.Sym. We switch from using the one for Quotient because it does not require DecidableEq.

Diff
@@ -161,37 +161,37 @@ def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
         simp [or_comm]⟩
 #align sym2.game_add Sym2.GameAdd
 
-theorem gameAdd_iff :
-    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.swap y := by
+theorem gameAdd_iff : ∀ {x y : α × α},
+    GameAdd rα (Sym2.mk x) (Sym2.mk y) ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.swap y := by
   rintro ⟨_, _⟩ ⟨_, _⟩
   rfl
 #align sym2.game_add_iff Sym2.gameAdd_iff
 
 theorem gameAdd_mk'_iff {a₁ a₂ b₁ b₂ : α} :
-    GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ ↔
+    GameAdd rα s(a₁, b₁) s(a₂, b₂) ↔
       Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂) :=
   Iff.rfl
 #align sym2.game_add_mk_iff Sym2.gameAdd_mk'_iff
 
 theorem _root_.Prod.GameAdd.to_sym2 {a₁ a₂ b₁ b₂ : α} (h : Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂)) :
-    Sym2.GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ :=
+    Sym2.GameAdd rα s(a₁, b₁) s(a₂, b₂) :=
   gameAdd_mk'_iff.2 <| Or.inl <| h
 #align prod.game_add.to_sym2 Prod.GameAdd.to_sym2
 
-theorem GameAdd.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(a₂, b)⟧ :=
+theorem GameAdd.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα s(a₁, b) s(a₂, b) :=
   (Prod.GameAdd.fst h).to_sym2
 #align sym2.game_add.fst Sym2.GameAdd.fst
 
-theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a, b₁)⟧ ⟦(a, b₂)⟧ :=
+theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα s(a, b₁) s(a, b₂) :=
   (Prod.GameAdd.snd h).to_sym2
 #align sym2.game_add.snd Sym2.GameAdd.snd
 
-theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ := by
+theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα s(a₁, b) s(b, a₂) := by
   rw [Sym2.eq_swap]
   exact GameAdd.snd h
 #align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
 
-theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ := by
+theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα s(b, a₁) s(a₂, b) := by
   rw [Sym2.eq_swap]
   exact GameAdd.fst h
 #align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
@@ -199,7 +199,7 @@ theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦
 end Sym2
 
 theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) :
-    Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ := by
+    Acc (Sym2.GameAdd rα) s(a, b) := by
   induction' ha with a _ iha generalizing b
   induction' hb with b hb ihb
   refine' Acc.intro _ fun s => _
@@ -222,9 +222,11 @@ theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameA
 
 namespace Sym2
 
+attribute [local instance] Sym2.Rel.setoid
+
 /-- Recursion on the well-founded `Sym2.GameAdd` relation. -/
 def GameAdd.fix {C : α → α → Sort*} (hr : WellFounded rα)
-    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα s(a₂, b₂) s(a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a b : α) :
     C a b := by
   -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
   have := hr.sym2_gameAdd
@@ -234,7 +236,7 @@ def GameAdd.fix {C : α → α → Sort*} (hr : WellFounded rα)
 #align sym2.game_add.fix Sym2.GameAdd.fix
 
 theorem GameAdd.fix_eq {C : α → α → Sort*} (hr : WellFounded rα)
-    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα s(a₂, b₂) s(a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a b : α) :
     GameAdd.fix hr IH a b = IH a b fun a' b' _ => GameAdd.fix hr IH a' b' := by
   -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
   dsimp [GameAdd.fix]
@@ -244,7 +246,7 @@ theorem GameAdd.fix_eq {C : α → α → Sort*} (hr : WellFounded rα)
 /-- Induction on the well-founded `Sym2.GameAdd` relation. -/
 theorem GameAdd.induction {C : α → α → Prop} :
     WellFounded rα →
-      (∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) →
+      (∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα s(a₂, b₂) s(a₁, b₁) → C a₂ b₂) → C a₁ b₁) →
         ∀ a b, C a b :=
   GameAdd.fix
 #align sym2.game_add.induction Sym2.GameAdd.induction
fix: disable autoImplicit globally (#6528)

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

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

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

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

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

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

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

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

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

Diff
@@ -29,6 +29,8 @@ We also define `Sym2.GameAdd`, which is the unordered pair analog of `Prod.GameA
 decreases at a time.
 -/
 
+set_option autoImplicit true
+
 
 variable {α β : Type*} {rα : α → α → Prop} {rβ : β → β → Prop}
 
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
@@ -30,7 +30,7 @@ decreases at a time.
 -/
 
 
-variable {α β : Type _} {rα : α → α → Prop} {rβ : β → β → Prop}
+variable {α β : Type*} {rα : α → α → Prop} {rβ : β → β → Prop}
 
 /-! ### `Prod.GameAdd` -/
 
@@ -118,14 +118,14 @@ namespace Prod
 
 /-- Recursion on the well-founded `Prod.GameAdd` relation.
   Note that it's strictly more general to recurse on the lexicographic order instead. -/
-def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
+def GameAdd.fix {C : α → β → Sort*} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     C a b :=
   @WellFounded.fix (α × β) (fun x => C x.1 x.2) _ (hα.prod_gameAdd hβ)
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) ⟨a, b⟩
 #align prod.game_add.fix Prod.GameAdd.fix
 
-theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
+theorem GameAdd.fix_eq {C : α → β → Sort*} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     GameAdd.fix hα hβ IH a b = IH a b fun a' b' _ => GameAdd.fix hα hβ IH a' b' :=
   WellFounded.fix_eq _ _ _
@@ -221,7 +221,7 @@ theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameA
 namespace Sym2
 
 /-- Recursion on the well-founded `Sym2.GameAdd` relation. -/
-def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
+def GameAdd.fix {C : α → α → Sort*} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
     C a b := by
   -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
@@ -231,7 +231,7 @@ def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
 #align sym2.game_add.fix Sym2.GameAdd.fix
 
-theorem GameAdd.fix_eq {C : α → α → Sort _} (hr : WellFounded rα)
+theorem GameAdd.fix_eq {C : α → α → Sort*} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
     GameAdd.fix hr IH a b = IH a b fun a' b' _ => GameAdd.fix hr IH a' b' := by
   -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
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,15 +2,12 @@
 Copyright (c) 2022 Junyan Xu. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
-
-! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit fee218fb033b2fd390c447f8be27754bc9093be9
-! Please do not edit these lines, except to modify the commit id
-! if you have ported upstream changes.
 -/
 import Mathlib.Data.Sym.Sym2
 import Mathlib.Logic.Relation
 
+#align_import order.game_add from "leanprover-community/mathlib"@"fee218fb033b2fd390c447f8be27754bc9093be9"
+
 /-!
 # Game addition relation
 
chore: add space after exacts (#4945)

Too often tempted to change these during other PRs, so doing a mass edit here.

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au>

Diff
@@ -62,10 +62,10 @@ theorem gameAdd_iff {rα rβ} {x y : α × β} :
     GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 := by
   constructor
   · rintro (@⟨a₁, a₂, b, h⟩ | @⟨a, b₁, b₂, h⟩)
-    exacts[Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
+    exacts [Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
   · revert x y
     rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ (⟨h, rfl : b₁ = b₂⟩ | ⟨h, rfl : a₁ = a₂⟩)
-    exacts[GameAdd.fst h, GameAdd.snd h]
+    exacts [GameAdd.fst h, GameAdd.snd h]
 #align prod.game_add_iff Prod.gameAdd_iff
 
 theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
@@ -106,7 +106,7 @@ theorem Acc.prod_gameAdd (ha : Acc rα a) (hb : Acc rβ b) :
   induction' hb with b hb ihb
   refine' Acc.intro _ fun h => _
   rintro (⟨ra⟩ | ⟨rb⟩)
-  exacts[iha _ ra (Acc.intro b hb), ihb _ rb]
+  exacts [iha _ ra (Acc.intro b hb), ihb _ rb]
 #align acc.prod_game_add Acc.prod_gameAdd
 
 /-- The `Prod.GameAdd` relation on well-founded inputs is well-founded.
chore: reenable eta, bump to nightly 2023-05-16 (#3414)

Now that leanprover/lean4#2210 has been merged, this PR:

  • removes all the set_option synthInstance.etaExperiment true commands (and some etaExperiment% term elaborators)
  • removes many but not quite all set_option maxHeartbeats commands
  • makes various other changes required to cope with leanprover/lean4#2210.

Co-authored-by: Scott Morrison <scott.morrison@anu.edu.au> Co-authored-by: Scott Morrison <scott.morrison@gmail.com> Co-authored-by: Matthew Ballard <matt@mrb.email>

Diff
@@ -226,15 +226,20 @@ namespace Sym2
 /-- Recursion on the well-founded `Sym2.GameAdd` relation. -/
 def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
-    C a b :=
-  @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ hr.sym2_gameAdd.of_quotient_lift₂
+    C a b := by
+  -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
+  have := hr.sym2_gameAdd
+  dsimp only [GameAdd, lift₂, FunLike.coe, EquivLike.coe] at this
+  exact @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ this.of_quotient_lift₂
     (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
 #align sym2.game_add.fix Sym2.GameAdd.fix
 
 theorem GameAdd.fix_eq {C : α → α → Sort _} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
-    GameAdd.fix hr IH a b = IH a b fun a' b' _ => GameAdd.fix hr IH a' b' :=
-  WellFounded.fix_eq _ _ _
+    GameAdd.fix hr IH a b = IH a b fun a' b' _ => GameAdd.fix hr IH a' b' := by
+  -- Porting note: this was refactored for #3414 (reenableeta), and could perhaps be cleaned up.
+  dsimp [GameAdd.fix]
+  exact WellFounded.fix_eq _ _ _
 #align sym2.game_add.fix_eq Sym2.GameAdd.fix_eq
 
 /-- Induction on the well-founded `Sym2.GameAdd` relation. -/
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
@@ -59,8 +59,7 @@ inductive GameAdd : α × β → α × β → Prop
 #align prod.game_add Prod.GameAdd
 
 theorem gameAdd_iff {rα rβ} {x y : α × β} :
-    GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
-  by
+    GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 := by
   constructor
   · rintro (@⟨a₁, a₂, b, h⟩ | @⟨a, b₁, b₂, h⟩)
     exacts[Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
@@ -157,16 +156,14 @@ namespace Sym2
 def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
   Sym2.lift₂
     ⟨fun a₁ b₁ a₂ b₂ => Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂),
-      fun a₁ b₁ a₂ b₂ =>
-      by
-      dsimp
-      rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
-      simp [or_comm]⟩
+      fun a₁ b₁ a₂ b₂ => by
+        dsimp
+        rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
+        simp [or_comm]⟩
 #align sym2.game_add Sym2.GameAdd
 
 theorem gameAdd_iff :
-    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.swap y :=
-  by
+    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.swap y := by
   rintro ⟨_, _⟩ ⟨_, _⟩
   rfl
 #align sym2.game_add_iff Sym2.gameAdd_iff
@@ -190,22 +187,20 @@ theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a,
   (Prod.GameAdd.snd h).to_sym2
 #align sym2.game_add.snd Sym2.GameAdd.snd
 
-theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
-  by
+theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ := by
   rw [Sym2.eq_swap]
   exact GameAdd.snd h
 #align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
 
-theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
-  by
+theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ := by
   rw [Sym2.eq_swap]
   exact GameAdd.fst h
 #align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
 
 end Sym2
 
-theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) : Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ :=
-  by
+theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) :
+    Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ := by
   induction' ha with a _ iha generalizing b
   induction' hb with b hb ihb
   refine' Acc.intro _ fun s => _
feat: make Acc.rec and many related defs computable (#3535)

Lean 4 code generator has had no native supports for Acc.rec. This PR makes Acc.rec computable. This change makes many defs computable. Especially, computable PFun.fix and Part.hasFix enables us to reason about partial functions. This PR also renames some instances and gives PFun.lift @[coe] attr.

Diff
@@ -122,7 +122,7 @@ namespace Prod
 
 /-- Recursion on the well-founded `Prod.GameAdd` relation.
   Note that it's strictly more general to recurse on the lexicographic order instead. -/
-noncomputable def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
+def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
     C a b :=
   @WellFounded.fix (α × β) (fun x => C x.1 x.2) _ (hα.prod_gameAdd hβ)
@@ -229,7 +229,7 @@ theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameA
 namespace Sym2
 
 /-- Recursion on the well-founded `Sym2.GameAdd` relation. -/
-noncomputable def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
+def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
     (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
     C a b :=
   @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ hr.sym2_gameAdd.of_quotient_lift₂
feat: port changes to order/game_add (#2532)

Simultaneously ports various PRs on this file.

This also fixes a mis-ported alias in Mathlib/Order/RelIso/Basic.lean

Co-authored-by: Parcly Taxel <reddeloostw@gmail.com> Co-authored-by: Jeremy Tan Jie Rui <reddeloostw@gmail.com>

Diff
@@ -4,12 +4,12 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 
 ! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit 6f870fad180eb0f5d8f1e4f385216c25513cb2f8
+! leanprover-community/mathlib commit fee218fb033b2fd390c447f8be27754bc9093be9
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
+import Mathlib.Data.Sym.Sym2
 import Mathlib.Logic.Relation
-import Mathlib.Order.Basic
 
 /-!
 # Game addition relation
@@ -19,23 +19,29 @@ This file defines, given relations `rα : α → α → Prop` and `rβ : β →
 decreasing either entry (with respect to `rα` and `rβ`). It is so called since it models the
 subsequency relation on the addition of combinatorial games.
 
+We also define `Sym2.GameAdd`, which is the unordered pair analog of `Prod.GameAdd`.
+
 ## Main definitions and results
 
 - `Prod.GameAdd`: the game addition relation on ordered pairs.
 - `WellFounded.prod_gameAdd`: formalizes induction on ordered pairs, where exactly one entry
   decreases at a time.
 
-## Todo
-
-- Add custom `induction` and `fix` lemmas.
-- Define `Sym2.GameAdd`.
+- `Sym2.GameAdd`: the game addition relation on unordered pairs.
+- `WellFounded.sym2_gameAdd`: formalizes induction on unordered pairs, where exactly one entry
+decreases at a time.
 -/
 
 
-variable (rα : α → α → Prop) (rβ : β → β → Prop)
+variable {α β : Type _} {rα : α → α → Prop} {rβ : β → β → Prop}
+
+/-! ### `Prod.GameAdd` -/
+
 
 namespace Prod
 
+variable (rα rβ)
+
 /-- `Prod.GameAdd rα rβ x y` means that `x` can be reached from `y` by decreasing either entry with
   respect to the relations `rα` and `rβ`.
 
@@ -43,19 +49,48 @@ namespace Prod
   that `a₂ ⟶ a₁` is a valid move in game `α`, and `rβ b₁ b₂` means that `b₂ ⟶ b₁` is a valid move
   in game `β`, then `GameAdd rα rβ` specifies the valid moves in the juxtaposition of `α` and `β`:
   the player is free to choose one of the games and make a move in it, while leaving the other game
-  unchanged. -/
+  unchanged.
+
+  See `Sym2.GameAdd` for the unordered pair analog. -/
+
 inductive GameAdd : α × β → α × β → Prop
   | fst {a₁ a₂ b} : rα a₁ a₂ → GameAdd (a₁, b) (a₂, b)
   | snd {a b₁ b₂} : rβ b₁ b₂ → GameAdd (a, b₁) (a, b₂)
 #align prod.game_add Prod.GameAdd
 
-/-- `GameAdd` is a subrelation of `Prod.Lex`. -/
+theorem gameAdd_iff {rα rβ} {x y : α × β} :
+    GameAdd rα rβ x y ↔ rα x.1 y.1 ∧ x.2 = y.2 ∨ rβ x.2 y.2 ∧ x.1 = y.1 :=
+  by
+  constructor
+  · rintro (@⟨a₁, a₂, b, h⟩ | @⟨a, b₁, b₂, h⟩)
+    exacts[Or.inl ⟨h, rfl⟩, Or.inr ⟨h, rfl⟩]
+  · revert x y
+    rintro ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ (⟨h, rfl : b₁ = b₂⟩ | ⟨h, rfl : a₁ = a₂⟩)
+    exacts[GameAdd.fst h, GameAdd.snd h]
+#align prod.game_add_iff Prod.gameAdd_iff
+
+theorem gameAdd_mk_iff {rα rβ} {a₁ a₂ : α} {b₁ b₂ : β} :
+    GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ rα a₁ a₂ ∧ b₁ = b₂ ∨ rβ b₁ b₂ ∧ a₁ = a₂ :=
+  gameAdd_iff
+#align prod.game_add_mk_iff Prod.gameAdd_mk_iff
+
+@[simp]
+theorem gameAdd_swap_swap : ∀ a b : α × β, GameAdd rβ rα a.swap b.swap ↔ GameAdd rα rβ a b :=
+  fun ⟨a₁, b₁⟩ ⟨a₂, b₂⟩ => by rw [Prod.swap, Prod.swap, gameAdd_mk_iff, gameAdd_mk_iff, or_comm]
+#align prod.game_add_swap_swap Prod.gameAdd_swap_swap
+
+theorem gameAdd_swap_swap_mk (a₁ a₂ : α) (b₁ b₂ : β) :
+    GameAdd rα rβ (a₁, b₁) (a₂, b₂) ↔ GameAdd rβ rα (b₁, a₁) (b₂, a₂) :=
+  gameAdd_swap_swap rβ rα (b₁, a₁) (b₂, a₂)
+#align prod.game_add_swap_swap_mk Prod.gameAdd_swap_swap_mk
+
+/-- `Prod.GameAdd` is a subrelation of `Prod.Lex`. -/
 theorem gameAdd_le_lex : GameAdd rα rβ ≤ Prod.Lex rα rβ := fun _ _ h =>
   h.rec (Prod.Lex.left _ _) (Prod.Lex.right _)
 #align prod.game_add_le_lex Prod.gameAdd_le_lex
 
-/-- `Prod.RProd` is a subrelation of the transitive closure of `GameAdd`. -/
-theorem rprod_le_transGen_gameAdd : Prod.RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ)
+/-- `Prod.RProd` is a subrelation of the transitive closure of `Prod.GameAdd`. -/
+theorem rprod_le_transGen_gameAdd : RProd rα rβ ≤ Relation.TransGen (GameAdd rα rβ)
   | _, _, h => h.rec (by
       intro _ _ _ _ hα hβ
       exact Relation.TransGen.tail (Relation.TransGen.single $ GameAdd.fst hα) (GameAdd.snd hβ))
@@ -63,8 +98,6 @@ theorem rprod_le_transGen_gameAdd : Prod.RProd rα rβ ≤ Relation.TransGen (Ga
 
 end Prod
 
-variable {rα rβ}
-
 /-- If `a` is accessible under `rα` and `b` is accessible under `rβ`, then `(a, b)` is
   accessible under `Prod.GameAdd rα rβ`. Notice that `Prod.lexAccessible` requires the
   stronger condition `∀ b, Acc rβ b`. -/
@@ -84,3 +117,137 @@ theorem WellFounded.prod_gameAdd (hα : WellFounded rα) (hβ : WellFounded rβ)
     WellFounded (Prod.GameAdd rα rβ) :=
   ⟨fun ⟨a, b⟩ => (hα.apply a).prod_gameAdd (hβ.apply b)⟩
 #align well_founded.prod_game_add WellFounded.prod_gameAdd
+
+namespace Prod
+
+/-- Recursion on the well-founded `Prod.GameAdd` relation.
+  Note that it's strictly more general to recurse on the lexicographic order instead. -/
+noncomputable def GameAdd.fix {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
+    C a b :=
+  @WellFounded.fix (α × β) (fun x => C x.1 x.2) _ (hα.prod_gameAdd hβ)
+    (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) ⟨a, b⟩
+#align prod.game_add.fix Prod.GameAdd.fix
+
+theorem GameAdd.fix_eq {C : α → β → Sort _} (hα : WellFounded rα) (hβ : WellFounded rβ)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) (a : α) (b : β) :
+    GameAdd.fix hα hβ IH a b = IH a b fun a' b' _ => GameAdd.fix hα hβ IH a' b' :=
+  WellFounded.fix_eq _ _ _
+#align prod.game_add.fix_eq Prod.GameAdd.fix_eq
+
+/-- Induction on the well-founded `Prod.GameAdd` relation.
+  Note that it's strictly more general to induct on the lexicographic order instead. -/
+theorem GameAdd.induction {C : α → β → Prop} :
+    WellFounded rα →
+      WellFounded rβ →
+        (∀ a₁ b₁, (∀ a₂ b₂, GameAdd rα rβ (a₂, b₂) (a₁, b₁) → C a₂ b₂) → C a₁ b₁) → ∀ a b, C a b :=
+  GameAdd.fix
+#align prod.game_add.induction Prod.GameAdd.induction
+
+end Prod
+
+/-! ### `Sym2.GameAdd` -/
+
+namespace Sym2
+
+/-- `Sym2.GameAdd rα x y` means that `x` can be reached from `y` by decreasing either entry with
+  respect to the relation `rα`.
+
+  See `Prod.GameAdd` for the ordered pair analog. -/
+def GameAdd (rα : α → α → Prop) : Sym2 α → Sym2 α → Prop :=
+  Sym2.lift₂
+    ⟨fun a₁ b₁ a₂ b₂ => Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂),
+      fun a₁ b₁ a₂ b₂ =>
+      by
+      dsimp
+      rw [Prod.gameAdd_swap_swap_mk _ _ b₁ b₂ a₁ a₂, Prod.gameAdd_swap_swap_mk _ _ a₁ b₂ b₁ a₂]
+      simp [or_comm]⟩
+#align sym2.game_add Sym2.GameAdd
+
+theorem gameAdd_iff :
+    ∀ {x y : α × α}, GameAdd rα ⟦x⟧ ⟦y⟧ ↔ Prod.GameAdd rα rα x y ∨ Prod.GameAdd rα rα x.swap y :=
+  by
+  rintro ⟨_, _⟩ ⟨_, _⟩
+  rfl
+#align sym2.game_add_iff Sym2.gameAdd_iff
+
+theorem gameAdd_mk'_iff {a₁ a₂ b₁ b₂ : α} :
+    GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ ↔
+      Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂) ∨ Prod.GameAdd rα rα (b₁, a₁) (a₂, b₂) :=
+  Iff.rfl
+#align sym2.game_add_mk_iff Sym2.gameAdd_mk'_iff
+
+theorem _root_.Prod.GameAdd.to_sym2 {a₁ a₂ b₁ b₂ : α} (h : Prod.GameAdd rα rα (a₁, b₁) (a₂, b₂)) :
+    Sym2.GameAdd rα ⟦(a₁, b₁)⟧ ⟦(a₂, b₂)⟧ :=
+  gameAdd_mk'_iff.2 <| Or.inl <| h
+#align prod.game_add.to_sym2 Prod.GameAdd.to_sym2
+
+theorem GameAdd.fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(a₂, b)⟧ :=
+  (Prod.GameAdd.fst h).to_sym2
+#align sym2.game_add.fst Sym2.GameAdd.fst
+
+theorem GameAdd.snd {a b₁ b₂ : α} (h : rα b₁ b₂) : GameAdd rα ⟦(a, b₁)⟧ ⟦(a, b₂)⟧ :=
+  (Prod.GameAdd.snd h).to_sym2
+#align sym2.game_add.snd Sym2.GameAdd.snd
+
+theorem GameAdd.fst_snd {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(a₁, b)⟧ ⟦(b, a₂)⟧ :=
+  by
+  rw [Sym2.eq_swap]
+  exact GameAdd.snd h
+#align sym2.game_add.fst_snd Sym2.GameAdd.fst_snd
+
+theorem GameAdd.snd_fst {a₁ a₂ b : α} (h : rα a₁ a₂) : GameAdd rα ⟦(b, a₁)⟧ ⟦(a₂, b)⟧ :=
+  by
+  rw [Sym2.eq_swap]
+  exact GameAdd.fst h
+#align sym2.game_add.snd_fst Sym2.GameAdd.snd_fst
+
+end Sym2
+
+theorem Acc.sym2_gameAdd {a b} (ha : Acc rα a) (hb : Acc rα b) : Acc (Sym2.GameAdd rα) ⟦(a, b)⟧ :=
+  by
+  induction' ha with a _ iha generalizing b
+  induction' hb with b hb ihb
+  refine' Acc.intro _ fun s => _
+  induction' s using Sym2.inductionOn with c d
+  rw [Sym2.GameAdd]
+  dsimp
+  rintro ((rc | rd) | (rd | rc))
+  · exact iha c rc ⟨b, hb⟩
+  · exact ihb d rd
+  · rw [Sym2.eq_swap]
+    exact iha d rd ⟨b, hb⟩
+  · rw [Sym2.eq_swap]
+    exact ihb c rc
+#align acc.sym2_game_add Acc.sym2_gameAdd
+
+/-- The `Sym2.GameAdd` relation on well-founded inputs is well-founded. -/
+theorem WellFounded.sym2_gameAdd (h : WellFounded rα) : WellFounded (Sym2.GameAdd rα) :=
+  ⟨fun i => Sym2.inductionOn i fun x y => (h.apply x).sym2_gameAdd (h.apply y)⟩
+#align well_founded.sym2_game_add WellFounded.sym2_gameAdd
+
+namespace Sym2
+
+/-- Recursion on the well-founded `Sym2.GameAdd` relation. -/
+noncomputable def GameAdd.fix {C : α → α → Sort _} (hr : WellFounded rα)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    C a b :=
+  @WellFounded.fix (α × α) (fun x => C x.1 x.2) _ hr.sym2_gameAdd.of_quotient_lift₂
+    (fun ⟨x₁, x₂⟩ IH' => IH x₁ x₂ fun a' b' => IH' ⟨a', b'⟩) (a, b)
+#align sym2.game_add.fix Sym2.GameAdd.fix
+
+theorem GameAdd.fix_eq {C : α → α → Sort _} (hr : WellFounded rα)
+    (IH : ∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) (a b : α) :
+    GameAdd.fix hr IH a b = IH a b fun a' b' _ => GameAdd.fix hr IH a' b' :=
+  WellFounded.fix_eq _ _ _
+#align sym2.game_add.fix_eq Sym2.GameAdd.fix_eq
+
+/-- Induction on the well-founded `Sym2.GameAdd` relation. -/
+theorem GameAdd.induction {C : α → α → Prop} :
+    WellFounded rα →
+      (∀ a₁ b₁, (∀ a₂ b₂, Sym2.GameAdd rα ⟦(a₂, b₂)⟧ ⟦(a₁, b₁)⟧ → C a₂ b₂) → C a₁ b₁) →
+        ∀ a b, C a b :=
+  GameAdd.fix
+#align sym2.game_add.induction Sym2.GameAdd.induction
+
+end Sym2
Diff
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
 
 ! This file was ported from Lean 3 source module order.game_add
-! leanprover-community/mathlib commit 99e8971dc62f1f7ecf693d75e75fbbabd55849de
+! leanprover-community/mathlib commit 6f870fad180eb0f5d8f1e4f385216c25513cb2f8
 ! Please do not edit these lines, except to modify the commit id
 ! if you have ported upstream changes.
 -/
feat: port game_add doc changes (#1798)

Mathlib 3 pair: https://github.com/leanprover-community/mathlib/pull/18269

Diff
@@ -36,14 +36,17 @@ variable (rα : α → α → Prop) (rβ : β → β → Prop)
 
 namespace Prod
 
-/-- The "addition of games" relation in combinatorial game theory, on the product type: if
-  `rα a' a` means that `a ⟶ a'` is a valid move in game `α`, and `rβ b' b` means that `b ⟶ b'`
-  is a valid move in game `β`, then `GameAdd rα rβ` specifies the valid moves in the juxtaposition
-  of `α` and `β`: the player is free to choose one of the games and make a move in it,
-  while leaving the other game unchanged. -/
+/-- `Prod.GameAdd rα rβ x y` means that `x` can be reached from `y` by decreasing either entry with
+  respect to the relations `rα` and `rβ`.
+
+  It is so called, as it models game addition within combinatorial game theory. If `rα a₁ a₂` means
+  that `a₂ ⟶ a₁` is a valid move in game `α`, and `rβ b₁ b₂` means that `b₂ ⟶ b₁` is a valid move
+  in game `β`, then `GameAdd rα rβ` specifies the valid moves in the juxtaposition of `α` and `β`:
+  the player is free to choose one of the games and make a move in it, while leaving the other game
+  unchanged. -/
 inductive GameAdd : α × β → α × β → Prop
-  | fst {a' a b} : rα a' a → GameAdd (a', b) (a, b)
-  | snd {a b' b} : rβ b' b → GameAdd (a, b') (a, b)
+  | fst {a₁ a₂ b} : rα a₁ a₂ → GameAdd (a₁, b) (a₂, b)
+  | snd {a b₁ b₂} : rβ b₁ b₂ → GameAdd (a, b₁) (a, b₂)
 #align prod.game_add Prod.GameAdd
 
 /-- `GameAdd` is a subrelation of `Prod.Lex`. -/
@@ -74,7 +77,9 @@ theorem Acc.prod_gameAdd (ha : Acc rα a) (hb : Acc rβ b) :
   exacts[iha _ ra (Acc.intro b hb), ihb _ rb]
 #align acc.prod_game_add Acc.prod_gameAdd
 
-/-- The sum of two well-founded games is well-founded. -/
+/-- The `Prod.GameAdd` relation on well-founded inputs is well-founded.
+
+  In particular, the sum of two well-founded games is well-founded. -/
 theorem WellFounded.prod_gameAdd (hα : WellFounded rα) (hβ : WellFounded rβ) :
     WellFounded (Prod.GameAdd rα rβ) :=
   ⟨fun ⟨a, b⟩ => (hα.apply a).prod_gameAdd (hβ.apply b)⟩
chore: add source headers to ported theory files (#1094)

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

Diff
@@ -2,6 +2,11 @@
 Copyright (c) 2022 Junyan Xu. All rights reserved.
 Released under Apache 2.0 license as described in the file LICENSE.
 Authors: Junyan Xu
+
+! This file was ported from Lean 3 source module order.game_add
+! leanprover-community/mathlib commit 99e8971dc62f1f7ecf693d75e75fbbabd55849de
+! Please do not edit these lines, except to modify the commit id
+! if you have ported upstream changes.
 -/
 import Mathlib.Logic.Relation
 import Mathlib.Order.Basic

Dependencies 6 + 176

177 files ported (96.7%)
80961 lines ported (97.4%)
Show graph

The unported dependencies are