l3lab/ntp-mathlib huggingface dataset:
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> 

Proof state:
case inl.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try 

Proof state:
case inl.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
rw [hστ, hτυ, swap_mul_self_mul]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> 

Proof state:
case inl.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try 

Proof state:
case inl.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
rw [hστ, hτυ, swap_mul_self_mul]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> 

Proof state:
case inr.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try 

Proof state:
case inr.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
rw [hστ, hτυ, swap_mul_self_mul]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> 

Proof state:
case inr.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try 

Proof state:
case inr.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
rw [hστ, hτυ, swap_mul_self_mul]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try rw [hστ, hτυ, swap_mul_self_mul] <;>
    

Proof state:
case inr.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = swap i j * υ
⊢ υ = υ ∨ υ = swap i j * υ

Next tactic:
simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ] -- porting note: should close goals, but doesn't
    · 

Proof state:
case inl.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ] -- porting note: should close goals, but doesn't
    · simp [hστ, hτυ]
    · 

Proof state:
case inl.inr
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = τ
hτυ : τ = swap i j * υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
simp [hστ, hτυ]
/-- `modSwap i j` contains permutations up to swapping `i` and `j`.

We use this to partition permutations in `Matrix.det_zero_of_row_eq`, such that each partition
sums up to `0`.
-/
def modSwap [DecidableEq α] (i j : α) : Setoid (Perm α) :=
  ⟨fun σ τ => σ = τ ∨ σ = swap i j * τ, fun σ => Or.inl (refl σ), fun {σ τ} h =>
    Or.casesOn h (fun h => Or.inl h.symm) fun h => Or.inr (by rw [h, swap_mul_self_mul]),
    fun {σ τ υ} hστ hτυ => by
    cases' hστ with hστ hστ <;> cases' hτυ with hτυ hτυ <;> try rw [hστ, hτυ, swap_mul_self_mul] <;>
    simp [hστ, hτυ] -- porting note: should close goals, but doesn't
    · simp [hστ, hτυ]
    · simp [hστ, hτυ]
    · 

Proof state:
case inr.inl
α : Type u
β : Type v
inst✝ : DecidableEq α
i j : α
σ τ υ : Perm α
hστ : σ = swap i j * τ
hτυ : τ = υ
⊢ σ = υ ∨ σ = swap i j * υ

Next tactic:
simp [hστ, hτυ]
theorem perm_inv_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x ∈ s, f x ∈ s) {y : α}
    (hy : y ∈ s) : f⁻¹ y ∈ s := by
  

Proof state:
α : Type u
β : Type v
s : Finset α
f : Perm α
h : ∀ x ∈ s, f x ∈ s
y : α
hy : y ∈ s
⊢ f⁻¹ y ∈ s

Next tactic:
have h0 : ∀ y ∈ s, ∃ (x : _) (hx : x ∈ s), y = (fun i (_ : i ∈ s) => f i) x hx :=
    Finset.surj_on_of_inj_on_of_card_le (fun x hx => (fun i _ => f i) x hx) (fun a ha => h a ha)
      (fun a₁ a₂ ha₁ ha₂ heq => (Equiv.apply_eq_iff_eq f).mp heq) rfl.ge
theorem perm_inv_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x ∈ s, f x ∈ s) {y : α}
    (hy : y ∈ s) : f⁻¹ y ∈ s := by
  have h0 : ∀ y ∈ s, ∃ (x : _) (hx : x ∈ s), y = (fun i (_ : i ∈ s) => f i) x hx :=
    Finset.surj_on_of_inj_on_of_card_le (fun x hx => (fun i _ => f i) x hx) (fun a ha => h a ha)
      (fun a₁ a₂ ha₁ ha₂ heq => (Equiv.apply_eq_iff_eq f).mp heq) rfl.ge
  

Proof state:
α : Type u
β : Type v
s : Finset α
f : Perm α
h : ∀ x ∈ s, f x ∈ s
y : α
hy : y ∈ s
h0 : ∀ y ∈ s, ∃ x, ∃ (hx : x ∈ s), y = (fun i x => f i) x hx
⊢ f⁻¹ y ∈ s

Next tactic:
obtain ⟨y2, hy2, heq⟩ := h0 y hy
theorem perm_inv_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x ∈ s, f x ∈ s) {y : α}
    (hy : y ∈ s) : f⁻¹ y ∈ s := by
  have h0 : ∀ y ∈ s, ∃ (x : _) (hx : x ∈ s), y = (fun i (_ : i ∈ s) => f i) x hx :=
    Finset.surj_on_of_inj_on_of_card_le (fun x hx => (fun i _ => f i) x hx) (fun a ha => h a ha)
      (fun a₁ a₂ ha₁ ha₂ heq => (Equiv.apply_eq_iff_eq f).mp heq) rfl.ge
  obtain ⟨y2, hy2, heq⟩ := h0 y hy
  

Proof state:
case intro.intro
α : Type u
β : Type v
s : Finset α
f : Perm α
h : ∀ x ∈ s, f x ∈ s
y : α
hy : y ∈ s
h0 : ∀ y ∈ s, ∃ x, ∃ (hx : x ∈ s), y = (fun i x => f i) x hx
y2 : α
hy2 : y2 ∈ s
heq : y = (fun i x => f i) y2 hy2
⊢ f⁻¹ y ∈ s

Next tactic:
convert hy2
theorem perm_inv_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x ∈ s, f x ∈ s) {y : α}
    (hy : y ∈ s) : f⁻¹ y ∈ s := by
  have h0 : ∀ y ∈ s, ∃ (x : _) (hx : x ∈ s), y = (fun i (_ : i ∈ s) => f i) x hx :=
    Finset.surj_on_of_inj_on_of_card_le (fun x hx => (fun i _ => f i) x hx) (fun a ha => h a ha)
      (fun a₁ a₂ ha₁ ha₂ heq => (Equiv.apply_eq_iff_eq f).mp heq) rfl.ge
  obtain ⟨y2, hy2, heq⟩ := h0 y hy
  convert hy2
  

Proof state:
case h.e'_4
α : Type u
β : Type v
s : Finset α
f : Perm α
h : ∀ x ∈ s, f x ∈ s
y : α
hy : y ∈ s
h0 : ∀ y ∈ s, ∃ x, ∃ (hx : x ∈ s), y = (fun i x => f i) x hx
y2 : α
hy2 : y2 ∈ s
heq : y = (fun i x => f i) y2 hy2
⊢ f⁻¹ y = y2

Next tactic:
rw [heq]
theorem perm_inv_on_of_perm_on_finset {s : Finset α} {f : Perm α} (h : ∀ x ∈ s, f x ∈ s) {y : α}
    (hy : y ∈ s) : f⁻¹ y ∈ s := by
  have h0 : ∀ y ∈ s, ∃ (x : _) (hx : x ∈ s), y = (fun i (_ : i ∈ s) => f i) x hx :=
    Finset.surj_on_of_inj_on_of_card_le (fun x hx => (fun i _ => f i) x hx) (fun a ha => h a ha)
      (fun a₁ a₂ ha₁ ha₂ heq => (Equiv.apply_eq_iff_eq f).mp heq) rfl.ge
  obtain ⟨y2, hy2, heq⟩ := h0 y hy
  convert hy2
  rw [heq]
  

Proof state:
case h.e'_4
α : Type u
β : Type v
s : Finset α
f : Perm α
h : ∀ x ∈ s, f x ∈ s
y : α
hy : y ∈ s
h0 : ∀ y ∈ s, ∃ x, ∃ (hx : x ∈ s), y = (fun i x => f i) x hx
y2 : α
hy2 : y2 ∈ s
heq : y = (fun i x => f i) y2 hy2
⊢ f⁻¹ ((fun i x => f i) y2 hy2) = y2

Next tactic:
simp only [inv_apply_self]
theorem perm_inv_mapsTo_of_mapsTo (f : Perm α) {s : Set α} [Finite s] (h : Set.MapsTo f s s) :
    Set.MapsTo (f⁻¹ : _) s s := by
  

Proof state:
α : Type u
β : Type v
f : Perm α
s : Set α
inst✝ : Finite ↑s
h : Set.MapsTo (⇑f) s s
⊢ Set.MapsTo (⇑f⁻¹) s s

Next tactic:
cases nonempty_fintype s
theorem perm_inv_mapsTo_of_mapsTo (f : Perm α) {s : Set α} [Finite s] (h : Set.MapsTo f s s) :
    Set.MapsTo (f⁻¹ : _) s s := by
  cases nonempty_fintype s;
    

Proof state:
case intro
α : Type u
β : Type v
f : Perm α
s : Set α
inst✝ : Finite ↑s
h : Set.MapsTo (⇑f) s s
val✝ : Fintype ↑s
⊢ Set.MapsTo (⇑f⁻¹) s s

Next tactic:
exact fun x hx =>
      Set.mem_toFinset.mp <|
        perm_inv_on_of_perm_on_finset
          (fun a ha => Set.mem_toFinset.mpr (h (Set.mem_toFinset.mp ha)))
          (Set.mem_toFinset.mpr hx)
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  

Proof state:
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl) ↔ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
cases nonempty_fintype m
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  

Proof state:
case intro
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝ : Fintype m
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl) ↔ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
cases nonempty_fintype n
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  

Proof state:
case intro.intro
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl) ↔ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
constructor
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( 

Proof state:
case intro.intro.mp
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl) → Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
intro h
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      

Proof state:
case intro.intro.mp
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        cases' hx : σ x with l r
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        

Proof state:
case intro.intro.mp
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
rw [← perm_inv_mapsTo_iff_mapsTo] at h
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        

Proof state:
case intro.intro.mp
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inl) (Set.range Sum.inl)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)

Next tactic:
intro x
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        

Proof state:
case intro.intro.mp
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inl) (Set.range Sum.inl)
x : m ⊕ n
⊢ x ∈ Set.range Sum.inr → σ x ∈ Set.range Sum.inr

Next tactic:
cases' hx : σ x with l r
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( 

Proof state:
case intro.intro.mpr
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr) → Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)

Next tactic:
intro h
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      

Proof state:
case intro.intro.mpr
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)

Next tactic:
classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        cases' hx : σ x with l r
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        

Proof state:
case intro.intro.mpr
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ) (Set.range Sum.inr) (Set.range Sum.inr)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)

Next tactic:
rw [← perm_inv_mapsTo_iff_mapsTo] at h
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        

Proof state:
case intro.intro.mpr
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inr) (Set.range Sum.inr)
⊢ Set.MapsTo (⇑σ) (Set.range Sum.inl) (Set.range Sum.inl)

Next tactic:
intro x
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        

Proof state:
case intro.intro.mpr
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inr) (Set.range Sum.inr)
x : m ⊕ n
⊢ x ∈ Set.range Sum.inl → σ x ∈ Set.range Sum.inl

Next tactic:
cases' hx : σ x with l r
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        cases' hx : σ x with l r)
  · 

Proof state:
case intro.intro.mp.inl
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inl) (Set.range Sum.inl)
x : m ⊕ n
l : m
hx : σ x = Sum.inl l
⊢ x ∈ Set.range Sum.inr → Sum.inl l ∈ Set.range Sum.inr

Next tactic:
rintro ⟨a, rfl⟩
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        cases' hx : σ x with l r)
  · rintro ⟨a, rfl⟩
    

Proof state:
case intro.intro.mp.inl.intro
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inl) (Set.range Sum.inl)
l : m
a : n
hx : σ (Sum.inr a) = Sum.inl l
⊢ Sum.inl l ∈ Set.range Sum.inr

Next tactic:
obtain ⟨y, hy⟩ := h ⟨l, rfl⟩
theorem perm_mapsTo_inl_iff_mapsTo_inr {m n : Type*} [Finite m] [Finite n] (σ : Perm (Sum m n)) :
    Set.MapsTo σ (Set.range Sum.inl) (Set.range Sum.inl) ↔
      Set.MapsTo σ (Set.range Sum.inr) (Set.range Sum.inr) := by
  cases nonempty_fintype m
  cases nonempty_fintype n
  constructor <;>
    ( intro h
      classical
        rw [← perm_inv_mapsTo_iff_mapsTo] at h
        intro x
        cases' hx : σ x with l r)
  · rintro ⟨a, rfl⟩
    obtain ⟨y, hy⟩ := h ⟨l, rfl⟩
    

Proof state:
case intro.intro.mp.inl.intro.intro
α : Type u
β : Type v
m : Type u_1
n : Type u_2
inst✝¹ : Finite m
inst✝ : Finite n
σ : Perm (m ⊕ n)
val✝¹ : Fintype m
val✝ : Fintype n
h : Set.MapsTo (⇑σ⁻¹) (Set.range Sum.inl) (Set.range Sum.inl)
l : m
a : n
hx : σ (Sum.inr a) = Sum.inl l
y : m
hy : Sum.inl y = σ⁻¹ (Sum.inl l)
⊢ Sum.inl l ∈ Set.range Sum.inr

Next tactic:
rw [← hx, σ.inv_apply_self] at hy