l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem ratio_trans (e : X ≃ᵈ Y) (e' : Y ≃ᵈ Z) : ratio (e.trans e') = ratio e * ratio e' := by
  -- If `X` is trivial, then so is `Y`, otherwise we apply `Dilation.ratio_comp'`
  by_cases hX : ∀ x y : X, edist x y = 0 ∨ edist x y = ∞
  · have hY : ∀ x y : Y, edist x y = 0 ∨ edist x y = ∞ := e.surjective.forall₂.2 fun x y ↦ by
      refine (hX x y).imp (fun h ↦ ?_) fun h ↦ ?_ <;> simp [*, Dilation.ratio_ne_zero]
    simp [Dilation.ratio_of_trivial, *]
  push_neg at hX
  

Proof state:
case neg
X : Type u_1
Y : Type u_2
Z : Type u_3
inst✝² : PseudoEMetricSpace X
inst✝¹ : PseudoEMetricSpace Y
inst✝ : PseudoEMetricSpace Z
e : X ≃ᵈ Y
e' : Y ≃ᵈ Z
hX : ∃ x y, edist x y ≠ 0 ∧ edist x y ≠ ⊤
⊢ ratio (trans e e') = ratio e * ratio e'

Next tactic:
exact (Dilation.ratio_comp' (g := e'.toDilation) (f := e.toDilation) hX).trans (mul_comm _ _)
@[simp]
theorem ratio_symm (e : X ≃ᵈ Y) : ratio e.symm = (ratio e)⁻¹ :=
  eq_inv_of_mul_eq_one_left <| by 

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
inst✝² : PseudoEMetricSpace X
inst✝¹ : PseudoEMetricSpace Y
inst✝ : PseudoEMetricSpace Z
e : X ≃ᵈ Y
⊢ ratio (symm e) * ratio e = 1

Next tactic:
rw [← ratio_trans, symm_trans_self, ratio_refl]
@[norm_cast]
theorem coe_pow (e : X ≃ᵈ X) (n : ℕ) : ⇑(e ^ n) = e^[n] := by
  

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
inst✝² : PseudoEMetricSpace X
inst✝¹ : PseudoEMetricSpace Y
inst✝ : PseudoEMetricSpace Z
e : X ≃ᵈ X
n : ℕ
⊢ ⇑(e ^ n) = (⇑e)^[n]

Next tactic:
rw [← coe_toEquiv, ← toPerm_apply, map_pow, Equiv.Perm.coe_pow]
@[norm_cast]
theorem coe_pow (e : X ≃ᵈ X) (n : ℕ) : ⇑(e ^ n) = e^[n] := by
  rw [← coe_toEquiv, ← toPerm_apply, map_pow, Equiv.Perm.coe_pow]; 

Proof state:
X : Type u_1
Y : Type u_2
Z : Type u_3
inst✝² : PseudoEMetricSpace X
inst✝¹ : PseudoEMetricSpace Y
inst✝ : PseudoEMetricSpace Z
e : X ≃ᵈ X
n : ℕ
⊢ (⇑(toPerm e))^[n] = (⇑e)^[n]

Next tactic:
rfl
@[simp]
lemma map_cobounded (e : F) : map e (cobounded X) = cobounded Y := by
  

Proof state:
X : Type u_1
Y : Type u_2
F : Type u_3
inst✝² : PseudoMetricSpace X
inst✝¹ : PseudoMetricSpace Y
inst✝ : DilationEquivClass F X Y
e : F
⊢ map (⇑e) (cobounded X) = cobounded Y

Next tactic:
rw [← Dilation.comap_cobounded e, map_comap_of_surjective (EquivLike.surjective e)]
theorem zpow_apply_comm {α : Type*} (σ : Perm α) (m n : ℤ) {x : α} :
    (σ ^ m) ((σ ^ n) x) = (σ ^ n) ((σ ^ m) x) := by
  

Proof state:
α✝ : Type u
β : Type v
α : Type u_1
σ : Perm α
m n : ℤ
x : α
⊢ (σ ^ m) ((σ ^ n) x) = (σ ^ n) ((σ ^ m) x)

Next tactic:
rw [← Equiv.Perm.mul_apply, ← Equiv.Perm.mul_apply, zpow_mul_comm]
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  

Proof state:
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
⊢ Function.Injective ⇑(sumCongrHom α β)

Next tactic:
rintro ⟨⟩ ⟨⟩ h
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  

Proof state:
case mk.mk
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
⊢ (fst✝¹, snd✝¹) = (fst✝, snd✝)

Next tactic:
rw [Prod.mk.inj_iff]
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  

Proof state:
case mk.mk
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
⊢ fst✝¹ = fst✝ ∧ snd✝¹ = snd✝

Next tactic:
constructor
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> 

Proof state:
case mk.mk.left
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
⊢ fst✝¹ = fst✝

Next tactic:
ext i
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> 

Proof state:
case mk.mk.right
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
⊢ snd✝¹ = snd✝

Next tactic:
ext i
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> ext i
  · 

Proof state:
case mk.mk.left.H
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
i : α
⊢ fst✝¹ i = fst✝ i

Next tactic:
simpa using Equiv.congr_fun h (Sum.inl i)
theorem sumCongrHom_injective {α β : Type*} : Function.Injective (sumCongrHom α β) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> ext i
  · simpa using Equiv.congr_fun h (Sum.inl i)
  · 

Proof state:
case mk.mk.right.H
α✝ : Type u
β✝ : Type v
α : Type u_1
β : Type u_2
fst✝¹ : Perm α
snd✝¹ : Perm β
fst✝ : Perm α
snd✝ : Perm β
h : (sumCongrHom α β) (fst✝¹, snd✝¹) = (sumCongrHom α β) (fst✝, snd✝)
i : β
⊢ snd✝¹ i = snd✝ i

Next tactic:
simpa using Equiv.congr_fun h (Sum.inr i)
theorem sigmaCongrRightHom_injective {α : Type*} {β : α → Type*} :
    Function.Injective (sigmaCongrRightHom β) := by
  

Proof state:
α✝ : Type u
β✝ : Type v
α : Type u_1
β : α → Type u_2
⊢ Function.Injective ⇑(sigmaCongrRightHom β)

Next tactic:
intro x y h
theorem sigmaCongrRightHom_injective {α : Type*} {β : α → Type*} :
    Function.Injective (sigmaCongrRightHom β) := by
  intro x y h
  

Proof state:
α✝ : Type u
β✝ : Type v
α : Type u_1
β : α → Type u_2
x y : (a : α) → Perm (β a)
h : (sigmaCongrRightHom β) x = (sigmaCongrRightHom β) y
⊢ x = y

Next tactic:
ext a b
theorem sigmaCongrRightHom_injective {α : Type*} {β : α → Type*} :
    Function.Injective (sigmaCongrRightHom β) := by
  intro x y h
  ext a b
  

Proof state:
case h.H
α✝ : Type u
β✝ : Type v
α : Type u_1
β : α → Type u_2
x y : (a : α) → Perm (β a)
h : (sigmaCongrRightHom β) x = (sigmaCongrRightHom β) y
a : α
b : β a
⊢ (x a) b = (y a) b

Next tactic:
simpa using Equiv.congr_fun h ⟨a, b⟩
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  

Proof state:
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
⊢ Function.Injective ⇑(subtypeCongrHom p)

Next tactic:
rintro ⟨⟩ ⟨⟩ h
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  

Proof state:
case mk.mk
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
⊢ (fst✝¹, snd✝¹) = (fst✝, snd✝)

Next tactic:
rw [Prod.mk.inj_iff]
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  

Proof state:
case mk.mk
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
⊢ fst✝¹ = fst✝ ∧ snd✝¹ = snd✝

Next tactic:
constructor
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> 

Proof state:
case mk.mk.left
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
⊢ fst✝¹ = fst✝

Next tactic:
ext i
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> 

Proof state:
case mk.mk.right
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
⊢ snd✝¹ = snd✝

Next tactic:
ext i
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> ext i <;> 

Proof state:
case mk.mk.left.H.a
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
i : { a // p a }
⊢ ↑(fst✝¹ i) = ↑(fst✝ i)

Next tactic:
simpa using Equiv.congr_fun h i
theorem subtypeCongrHom_injective (p : α → Prop) [DecidablePred p] :
    Function.Injective (subtypeCongrHom p) := by
  rintro ⟨⟩ ⟨⟩ h
  rw [Prod.mk.inj_iff]
  constructor <;> ext i <;> 

Proof state:
case mk.mk.right.H.a
α : Type u
β : Type v
p : α → Prop
inst✝ : DecidablePred p
fst✝¹ : Perm { a // p a }
snd✝¹ : Perm { a // ¬p a }
fst✝ : Perm { a // p a }
snd✝ : Perm { a // ¬p a }
h : (subtypeCongrHom p) (fst✝¹, snd✝¹) = (subtypeCongrHom p) (fst✝, snd✝)
i : { a // ¬p a }
⊢ ↑(snd✝¹ i) = ↑(snd✝ i)

Next tactic:
simpa using Equiv.congr_fun h i
/-- If the permutation `f` fixes the subtype `{x // p x}`, then this returns the permutation
  on `{x // p x}` induced by `f`. -/
def subtypePerm (f : Perm α) (h : ∀ x, p x ↔ p (f x)) : Perm { x // p x } where
  toFun := fun x => ⟨f x, (h _).1 x.2⟩
  invFun := fun x => ⟨f⁻¹ x, (h (f⁻¹ x)).2 <| by 

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
h : ∀ (x : α), p x ↔ p (f x)
x : { x // p x }
⊢ p (f (f⁻¹ ↑x))

Next tactic:
simpa using x.2
/-- If the permutation `f` fixes the subtype `{x // p x}`, then this returns the permutation
  on `{x // p x}` induced by `f`. -/
def subtypePerm (f : Perm α) (h : ∀ x, p x ↔ p (f x)) : Perm { x // p x } where
  toFun := fun x => ⟨f x, (h _).1 x.2⟩
  invFun := fun x => ⟨f⁻¹ x, (h (f⁻¹ x)).2 <| by simpa using x.2⟩
  left_inv _ := by 

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
h : ∀ (x : α), p x ↔ p (f x)
x✝ : { x // p x }
⊢ (fun x => { val := f⁻¹ ↑x, property := (_ : p (f⁻¹ ↑x)) })
      ((fun x => { val := f ↑x, property := (_ : p (f ↑x)) }) x✝) =
    x✝

Next tactic:
simp only [Perm.inv_apply_self, Subtype.coe_eta, Subtype.coe_mk]
/-- If the permutation `f` fixes the subtype `{x // p x}`, then this returns the permutation
  on `{x // p x}` induced by `f`. -/
def subtypePerm (f : Perm α) (h : ∀ x, p x ↔ p (f x)) : Perm { x // p x } where
  toFun := fun x => ⟨f x, (h _).1 x.2⟩
  invFun := fun x => ⟨f⁻¹ x, (h (f⁻¹ x)).2 <| by simpa using x.2⟩
  left_inv _ := by simp only [Perm.inv_apply_self, Subtype.coe_eta, Subtype.coe_mk]
  right_inv _ := by 

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
h : ∀ (x : α), p x ↔ p (f x)
x✝ : { x // p x }
⊢ (fun x => { val := f ↑x, property := (_ : p (f ↑x)) })
      ((fun x => { val := f⁻¹ ↑x, property := (_ : p (f⁻¹ ↑x)) }) x✝) =
    x✝

Next tactic:
simp only [Perm.apply_inv_self, Subtype.coe_eta, Subtype.coe_mk]
private theorem inv_aux : (∀ x, p x ↔ p (f x)) ↔ ∀ x, p x ↔ p (f⁻¹ x) :=
  f⁻¹.surjective.forall.trans <| by 

Proof state:
α : Type u
β : Type v
p : α → Prop
f : Perm α
⊢ (∀ (x : α), p (f⁻¹ x) ↔ p (f (f⁻¹ x))) ↔ ∀ (x : α), p x ↔ p (f⁻¹ x)

Next tactic:
simp_rw [f.apply_inv_self, Iff.comm]
@[simp]
theorem subtypePerm_pow (f : Perm α) (n : ℕ) (hf) :
    (f.subtypePerm hf : Perm { x // p x }) ^ n = (f ^ n).subtypePerm (pow_aux hf) := by
  

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
n : ℕ
hf : ∀ (x : α), p x ↔ p (f x)
⊢ subtypePerm f hf ^ n = subtypePerm (f ^ n) (_ : ∀ (x : α), p x ↔ p ((f ^ n) x))

Next tactic:
induction' n with n ih
@[simp]
theorem subtypePerm_pow (f : Perm α) (n : ℕ) (hf) :
    (f.subtypePerm hf : Perm { x // p x }) ^ n = (f ^ n).subtypePerm (pow_aux hf) := by
  induction' n with n ih
  · 

Proof state:
case zero
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
⊢ subtypePerm f hf ^ Nat.zero = subtypePerm (f ^ Nat.zero) (_ : ∀ (x : α), p x ↔ p ((f ^ Nat.zero) x))

Next tactic:
simp
@[simp]
theorem subtypePerm_pow (f : Perm α) (n : ℕ) (hf) :
    (f.subtypePerm hf : Perm { x // p x }) ^ n = (f ^ n).subtypePerm (pow_aux hf) := by
  induction' n with n ih
  · simp
  · 

Proof state:
case succ
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
n : ℕ
ih : subtypePerm f hf ^ n = subtypePerm (f ^ n) (_ : ∀ (x : α), p x ↔ p ((f ^ n) x))
⊢ subtypePerm f hf ^ Nat.succ n = subtypePerm (f ^ Nat.succ n) (_ : ∀ (x : α), p x ↔ p ((f ^ Nat.succ n) x))

Next tactic:
simp_rw [pow_succ', ih, subtypePerm_mul]
private theorem zpow_aux (hf : ∀ x, p x ↔ p (f x)) : ∀ {n : ℤ} (x), p x ↔ p ((f ^ n) x)
  | Int.ofNat n => pow_aux hf
  | Int.negSucc n => by
    

Proof state:
α : Type u
β : Type v
p : α → Prop
f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
n : ℕ
⊢ ∀ (x : α), p x ↔ p ((f ^ Int.negSucc n) x)

Next tactic:
rw [zpow_negSucc]
private theorem zpow_aux (hf : ∀ x, p x ↔ p (f x)) : ∀ {n : ℤ} (x), p x ↔ p ((f ^ n) x)
  | Int.ofNat n => pow_aux hf
  | Int.negSucc n => by
    rw [zpow_negSucc]
    

Proof state:
α : Type u
β : Type v
p : α → Prop
f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
n : ℕ
⊢ ∀ (x : α), p x ↔ p ((f ^ (n + 1))⁻¹ x)

Next tactic:
exact inv_aux.1 (pow_aux hf)
@[simp]
theorem subtypePerm_zpow (f : Perm α) (n : ℤ) (hf) :
    (f.subtypePerm hf ^ n : Perm { x // p x }) = (f ^ n).subtypePerm (zpow_aux hf) := by
  

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
n : ℤ
hf : ∀ (x : α), p x ↔ p (f x)
⊢ subtypePerm f hf ^ n = subtypePerm (f ^ n) (_ : ∀ (x : α), p x ↔ p ((f ^ n) x))

Next tactic:
induction' n with n ih
@[simp]
theorem subtypePerm_zpow (f : Perm α) (n : ℤ) (hf) :
    (f.subtypePerm hf ^ n : Perm { x // p x }) = (f ^ n).subtypePerm (zpow_aux hf) := by
  induction' n with n ih
  · 

Proof state:
case ofNat
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
n : ℕ
⊢ subtypePerm f hf ^ Int.ofNat n = subtypePerm (f ^ Int.ofNat n) (_ : ∀ (x : α), p x ↔ p ((f ^ Int.ofNat n) x))

Next tactic:
exact subtypePerm_pow _ _ _
@[simp]
theorem subtypePerm_zpow (f : Perm α) (n : ℤ) (hf) :
    (f.subtypePerm hf ^ n : Perm { x // p x }) = (f ^ n).subtypePerm (zpow_aux hf) := by
  induction' n with n ih
  · exact subtypePerm_pow _ _ _
  · 

Proof state:
case negSucc
α : Type u
β : Type v
p : α → Prop
f✝ f : Perm α
hf : ∀ (x : α), p x ↔ p (f x)
ih : ℕ
⊢ subtypePerm f hf ^ Int.negSucc ih = subtypePerm (f ^ Int.negSucc ih) (_ : ∀ (x : α), p x ↔ p ((f ^ Int.negSucc ih) x))

Next tactic:
simp only [zpow_negSucc, subtypePerm_pow, subtypePerm_inv]
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
⊢ (ofSubtype (subtypePerm f h₁)) x = f x

Next tactic:
by_cases hx : p x
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    by_cases hx : p x
    · 

Proof state:
case pos
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
hx : p x
⊢ (ofSubtype (subtypePerm f h₁)) x = f x

Next tactic:
exact (subtypePerm f h₁).extendDomain_apply_subtype _ hx
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    by_cases hx : p x
    · exact (subtypePerm f h₁).extendDomain_apply_subtype _ hx
    · 

Proof state:
case neg
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
hx : ¬p x
⊢ (ofSubtype (subtypePerm f h₁)) x = f x

Next tactic:
rw [ofSubtype, MonoidHom.coe_mk]
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    by_cases hx : p x
    · exact (subtypePerm f h₁).extendDomain_apply_subtype _ hx
    · rw [ofSubtype, MonoidHom.coe_mk]
      -- Porting note: added `dsimp`
      

Proof state:
case neg
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
hx : ¬p x
⊢ ({ toFun := fun f => extendDomain f (Equiv.refl { x // p x }),
          map_one' := (_ : extendDomain 1 (Equiv.refl { x // p x }) = 1) }
        (subtypePerm f h₁))
      x =
    f x

Next tactic:
dsimp only [OneHom.coe_mk]
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    by_cases hx : p x
    · exact (subtypePerm f h₁).extendDomain_apply_subtype _ hx
    · rw [ofSubtype, MonoidHom.coe_mk]
      -- Porting note: added `dsimp`
      dsimp only [OneHom.coe_mk]
      

Proof state:
case neg
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
hx : ¬p x
⊢ (extendDomain (subtypePerm f h₁) (Equiv.refl { x // p x })) x = f x

Next tactic:
rw [Equiv.Perm.extendDomain_apply_not_subtype _ _ hx]
theorem ofSubtype_subtypePerm {f : Perm α} (h₁ : ∀ x, p x ↔ p (f x)) (h₂ : ∀ x, f x ≠ x → p x) :
    ofSubtype (subtypePerm f h₁) = f :=
  Equiv.ext fun x => by
    by_cases hx : p x
    · exact (subtypePerm f h₁).extendDomain_apply_subtype _ hx
    · rw [ofSubtype, MonoidHom.coe_mk]
      -- Porting note: added `dsimp`
      dsimp only [OneHom.coe_mk]
      rw [Equiv.Perm.extendDomain_apply_not_subtype _ _ hx]
      

Proof state:
case neg
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm α
h₁ : ∀ (x : α), p x ↔ p (f x)
h₂ : ∀ (x : α), f x ≠ x → p x
x : α
hx : ¬p x
⊢ x = f x

Next tactic:
exact not_not.mp fun h => hx (h₂ x (Ne.symm h))
theorem mem_iff_ofSubtype_apply_mem (f : Perm (Subtype p)) (x : α) :
    p x ↔ p ((ofSubtype f : α → α) x) :=
  if h : p x then by
    

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm (Subtype p)
x : α
h : p x
⊢ p x ↔ p ((ofSubtype f) x)

Next tactic:
simpa only [h, true_iff_iff, MonoidHom.coe_mk, ofSubtype_apply_of_mem f h] using (f ⟨x, h⟩).2
theorem mem_iff_ofSubtype_apply_mem (f : Perm (Subtype p)) (x : α) :
    p x ↔ p ((ofSubtype f : α → α) x) :=
  if h : p x then by
    simpa only [h, true_iff_iff, MonoidHom.coe_mk, ofSubtype_apply_of_mem f h] using (f ⟨x, h⟩).2
  else by 

Proof state:
α : Type u
β : Type v
p : α → Prop
f✝ : Perm α
inst✝ : DecidablePred p
a : α
f : Perm (Subtype p)
x : α
h : ¬p x
⊢ p x ↔ p ((ofSubtype f) x)

Next tactic:
simp [h, ofSubtype_apply_of_not_mem f h]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
⊢ (swap x y * f) z = (f * swap (f⁻¹ x) (f⁻¹ y)) z

Next tactic:
simp only [Perm.mul_apply, swap_apply_def]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
⊢ (if f z = x then y else if f z = y then x else f z) = f (if z = f⁻¹ x then f⁻¹ y else if z = f⁻¹ y then f⁻¹ x else z)

Next tactic:
split_ifs
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝¹ : f z = x
h✝ : z = f⁻¹ x
⊢ y = f (f⁻¹ y)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝² : f z = x
h✝¹ : ¬z = f⁻¹ x
h✝ : z = f⁻¹ y
⊢ y = f (f⁻¹ x)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝² : f z = x
h✝¹ : ¬z = f⁻¹ x
h✝ : ¬z = f⁻¹ y
⊢ y = f z

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝² : ¬f z = x
h✝¹ : f z = y
h✝ : z = f⁻¹ x
⊢ x = f (f⁻¹ y)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝³ : ¬f z = x
h✝² : f z = y
h✝¹ : ¬z = f⁻¹ x
h✝ : z = f⁻¹ y
⊢ x = f (f⁻¹ x)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝³ : ¬f z = x
h✝² : f z = y
h✝¹ : ¬z = f⁻¹ x
h✝ : ¬z = f⁻¹ y
⊢ x = f z

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝² : ¬f z = x
h✝¹ : ¬f z = y
h✝ : z = f⁻¹ x
⊢ f z = f (f⁻¹ y)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case pos
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝³ : ¬f z = x
h✝² : ¬f z = y
h✝¹ : ¬z = f⁻¹ x
h✝ : z = f⁻¹ y
⊢ f z = f (f⁻¹ x)

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem swap_mul_eq_mul_swap (f : Perm α) (x y : α) : swap x y * f = f * swap (f⁻¹ x) (f⁻¹ y) :=
  Equiv.ext fun z => by
    simp only [Perm.mul_apply, swap_apply_def]
    split_ifs <;>
      

Proof state:
case neg
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y z : α
h✝³ : ¬f z = x
h✝² : ¬f z = y
h✝¹ : ¬z = f⁻¹ x
h✝ : ¬z = f⁻¹ y
⊢ f z = f z

Next tactic:
simp_all only [Perm.apply_inv_self, Perm.eq_inv_iff_eq, eq_self_iff_true, not_true]
theorem mul_swap_eq_swap_mul (f : Perm α) (x y : α) : f * swap x y = swap (f x) (f y) * f := by
  

Proof state:
α : Type u
β : Type v
inst✝ : DecidableEq α
f : Perm α
x y : α
⊢ f * swap x y = swap (f x) (f y) * f

Next tactic:
rw [swap_mul_eq_mul_swap, Perm.inv_apply_self, Perm.inv_apply_self]