l3lab/ntp-mathlib huggingface dataset:
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
⊢ IsCompact (closedBall x₀ r)

Next tactic:
let K := f ⁻¹' closedBall x₀ r
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  let K := f ⁻¹' closedBall x₀ r
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝¹ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K✝ : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K✝ f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
K : Set α := f ⁻¹' closedBall x₀ r
⊢ IsCompact (closedBall x₀ r)

Next tactic:
have A : IsClosed K := isClosed_ball.preimage f_cont
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  let K := f ⁻¹' closedBall x₀ r
  have A : IsClosed K := isClosed_ball.preimage f_cont
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝¹ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K✝ : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K✝ f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
K : Set α := f ⁻¹' closedBall x₀ r
A : IsClosed K
⊢ IsCompact (closedBall x₀ r)

Next tactic:
have B : IsBounded K := hK.isBounded_preimage isBounded_closedBall
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  let K := f ⁻¹' closedBall x₀ r
  have A : IsClosed K := isClosed_ball.preimage f_cont
  have B : IsBounded K := hK.isBounded_preimage isBounded_closedBall
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝¹ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K✝ : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K✝ f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
K : Set α := f ⁻¹' closedBall x₀ r
A : IsClosed K
B : IsBounded K
⊢ IsCompact (closedBall x₀ r)

Next tactic:
have : IsCompact K := isCompact_iff_isClosed_bounded.2 ⟨A, B⟩
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  let K := f ⁻¹' closedBall x₀ r
  have A : IsClosed K := isClosed_ball.preimage f_cont
  have B : IsBounded K := hK.isBounded_preimage isBounded_closedBall
  have : IsCompact K := isCompact_iff_isClosed_bounded.2 ⟨A, B⟩
  

Proof state:
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝¹ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K✝ : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K✝ f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
K : Set α := f ⁻¹' closedBall x₀ r
A : IsClosed K
B : IsBounded K
this : IsCompact K
⊢ IsCompact (closedBall x₀ r)

Next tactic:
convert this.image f_cont
/-- The image of a proper space under an expanding onto map is proper. -/
protected theorem properSpace {α : Type*} [MetricSpace α] {K : ℝ≥0} {f : α → β} [ProperSpace α]
    (hK : AntilipschitzWith K f) (f_cont : Continuous f) (hf : Function.Surjective f) :
    ProperSpace β := by
  refine ⟨fun x₀ r => ?_⟩
  let K := f ⁻¹' closedBall x₀ r
  have A : IsClosed K := isClosed_ball.preimage f_cont
  have B : IsBounded K := hK.isBounded_preimage isBounded_closedBall
  have : IsCompact K := isCompact_iff_isClosed_bounded.2 ⟨A, B⟩
  convert this.image f_cont
  

Proof state:
case h.e'_3
α✝ : Type u_1
β : Type u_2
γ : Type u_3
inst✝⁴ : PseudoMetricSpace α✝
inst✝³ : PseudoMetricSpace β
inst✝² : PseudoMetricSpace γ
K✝¹ : ℝ≥0
f✝ : α✝ → β
α : Type u_4
inst✝¹ : MetricSpace α
K✝ : ℝ≥0
f : α → β
inst✝ : ProperSpace α
hK : AntilipschitzWith K✝ f
f_cont : Continuous f
hf : Function.Surjective f
x₀ : β
r : ℝ
K : Set α := f ⁻¹' closedBall x₀ r
A : IsClosed K
B : IsBounded K
this : IsCompact K
⊢ closedBall x₀ r = f '' K

Next tactic:
exact (hf.image_preimage _).symm
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : IsBounded (image2 f s t)
⊢ IsBounded s ∨ IsBounded t

Next tactic:
contrapose! hst
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
⊢ ¬IsBounded (image2 f s t)

Next tactic:
obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
⊢ ¬IsBounded (image2 f s t)

Next tactic:
have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    apply hst.1
    rw [Set.image2_singleton_right] at h
    replace h := (hf b).isBounded_preimage h
    refine' h.subset (subset_preimage_image _ _)
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
⊢ ¬IsBounded (image2 f s {b})

Next tactic:
intro h
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
h : IsBounded (image2 f s {b})
⊢ False

Next tactic:
apply hst.1
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    apply hst.1
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
h : IsBounded (image2 f s {b})
⊢ IsBounded s

Next tactic:
rw [Set.image2_singleton_right] at h
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    apply hst.1
    rw [Set.image2_singleton_right] at h
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
h : IsBounded ((fun a => f a b) '' s)
⊢ IsBounded s

Next tactic:
replace h := (hf b).isBounded_preimage h
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    apply hst.1
    rw [Set.image2_singleton_right] at h
    replace h := (hf b).isBounded_preimage h
    

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
h : IsBounded ((fun a => f a b) ⁻¹' ((fun a => f a b) '' s))
⊢ IsBounded s

Next tactic:
refine' h.subset (subset_preimage_image _ _)
theorem isBounded_of_image2_left (f : α → β → γ) {K₁ : ℝ≥0}
    (hf : ∀ b, AntilipschitzWith K₁ fun a => f a b) {s : Set α} {t : Set β}
    (hst : IsBounded (Set.image2 f s t)) : IsBounded s ∨ IsBounded t := by
  contrapose! hst
  obtain ⟨b, hb⟩ : t.Nonempty := nonempty_of_not_isBounded hst.2
  have : ¬IsBounded (Set.image2 f s {b}) := by
    intro h
    apply hst.1
    rw [Set.image2_singleton_right] at h
    replace h := (hf b).isBounded_preimage h
    refine' h.subset (subset_preimage_image _ _)
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝² : PseudoMetricSpace α
inst✝¹ : PseudoMetricSpace β
inst✝ : PseudoMetricSpace γ
K : ℝ≥0
f✝ : α → β
f : α → β → γ
K₁ : ℝ≥0
hf : ∀ (b : β), AntilipschitzWith K₁ fun a => f a b
s : Set α
t : Set β
hst : ¬IsBounded s ∧ ¬IsBounded t
b : β
hb : b ∈ t
this : ¬IsBounded (image2 f s {b})
⊢ ¬IsBounded (image2 f s t)

Next tactic:
exact mt (IsBounded.subset · (image2_subset subset_rfl (singleton_subset_iff.mpr hb))) this
theorem LipschitzWith.to_rightInverse [PseudoEMetricSpace α] [PseudoEMetricSpace β] {K : ℝ≥0}
    {f : α → β} (hf : LipschitzWith K f) {g : β → α} (hg : Function.RightInverse g f) :
    AntilipschitzWith K g := fun x y => by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
K : ℝ≥0
f : α → β
hf : LipschitzWith K f
g : β → α
hg : Function.RightInverse g f
x y : β
⊢ edist x y ≤ ↑K * edist (g x) (g y)

Next tactic:
simpa only [hg _] using hf (g x) (g y)
@[symm]
theorem Disjoint.symm : Disjoint f g → Disjoint g f := by 

Proof state:
α : Type u_1
f g h : Perm α
⊢ Disjoint f g → Disjoint g f

Next tactic:
simp only [Disjoint, or_comm, imp_self]
theorem Disjoint.commute (h : Disjoint f g) : Commute f g :=
  Equiv.ext fun x =>
    (h x).elim
      (fun hf =>
        (h (g x)).elim (fun hg => by 

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
hf : f x = x
hg : f (g x) = g x
⊢ (f * g) x = (g * f) x

Next tactic:
simp [mul_apply, hf, hg]
theorem Disjoint.commute (h : Disjoint f g) : Commute f g :=
  Equiv.ext fun x =>
    (h x).elim
      (fun hf =>
        (h (g x)).elim (fun hg => by simp [mul_apply, hf, hg]) fun hg => by
          

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
hf : f x = x
hg : g (g x) = g x
⊢ (f * g) x = (g * f) x

Next tactic:
simp [mul_apply, hf, g.injective hg]
theorem Disjoint.commute (h : Disjoint f g) : Commute f g :=
  Equiv.ext fun x =>
    (h x).elim
      (fun hf =>
        (h (g x)).elim (fun hg => by simp [mul_apply, hf, hg]) fun hg => by
          simp [mul_apply, hf, g.injective hg])
      fun hg =>
      (h (f x)).elim (fun hf => by 

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
hg : g x = x
hf : f (f x) = f x
⊢ (f * g) x = (g * f) x

Next tactic:
simp [mul_apply, f.injective hf, hg]
theorem Disjoint.commute (h : Disjoint f g) : Commute f g :=
  Equiv.ext fun x =>
    (h x).elim
      (fun hf =>
        (h (g x)).elim (fun hg => by simp [mul_apply, hf, hg]) fun hg => by
          simp [mul_apply, hf, g.injective hg])
      fun hg =>
      (h (f x)).elim (fun hf => by simp [mul_apply, f.injective hf, hg]) fun hf => by
        

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
hg : g x = x
hf : g (f x) = f x
⊢ (f * g) x = (g * f) x

Next tactic:
simp [mul_apply, hf, hg]
@[simp]
theorem disjoint_refl_iff : Disjoint f f ↔ f = 1 := by
  

Proof state:
α : Type u_1
f g h : Perm α
⊢ Disjoint f f ↔ f = 1

Next tactic:
refine' ⟨fun h => _, fun h => h.symm ▸ disjoint_one_left 1⟩
@[simp]
theorem disjoint_refl_iff : Disjoint f f ↔ f = 1 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ disjoint_one_left 1⟩
  

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f f
⊢ f = 1

Next tactic:
ext x
@[simp]
theorem disjoint_refl_iff : Disjoint f f ↔ f = 1 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ disjoint_one_left 1⟩
  ext x
  

Proof state:
case H
α : Type u_1
f g h✝ : Perm α
h : Disjoint f f
x : α
⊢ f x = 1 x

Next tactic:
cases' h x with hx hx
@[simp]
theorem disjoint_refl_iff : Disjoint f f ↔ f = 1 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ disjoint_one_left 1⟩
  ext x
  cases' h x with hx hx <;> 

Proof state:
case H.inl
α : Type u_1
f g h✝ : Perm α
h : Disjoint f f
x : α
hx : f x = x
⊢ f x = 1 x

Next tactic:
simp [hx]
@[simp]
theorem disjoint_refl_iff : Disjoint f f ↔ f = 1 := by
  refine' ⟨fun h => _, fun h => h.symm ▸ disjoint_one_left 1⟩
  ext x
  cases' h x with hx hx <;> 

Proof state:
case H.inr
α : Type u_1
f g h✝ : Perm α
h : Disjoint f f
x : α
hx : f x = x
⊢ f x = 1 x

Next tactic:
simp [hx]
theorem Disjoint.inv_left (h : Disjoint f g) : Disjoint f⁻¹ g := by
  

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
⊢ Disjoint f⁻¹ g

Next tactic:
intro x
theorem Disjoint.inv_left (h : Disjoint f g) : Disjoint f⁻¹ g := by
  intro x
  

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
⊢ f⁻¹ x = x ∨ g x = x

Next tactic:
rw [inv_eq_iff_eq, eq_comm]
theorem Disjoint.inv_left (h : Disjoint f g) : Disjoint f⁻¹ g := by
  intro x
  rw [inv_eq_iff_eq, eq_comm]
  

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f g
x : α
⊢ f x = x ∨ g x = x

Next tactic:
exact h x
@[simp]
theorem disjoint_inv_left_iff : Disjoint f⁻¹ g ↔ Disjoint f g := by
  

Proof state:
α : Type u_1
f g h : Perm α
⊢ Disjoint f⁻¹ g ↔ Disjoint f g

Next tactic:
refine' ⟨fun h => _, Disjoint.inv_left⟩
@[simp]
theorem disjoint_inv_left_iff : Disjoint f⁻¹ g ↔ Disjoint f g := by
  refine' ⟨fun h => _, Disjoint.inv_left⟩
  

Proof state:
α : Type u_1
f g h✝ : Perm α
h : Disjoint f⁻¹ g
⊢ Disjoint f g

Next tactic:
convert h.inv_left
@[simp]
theorem disjoint_inv_right_iff : Disjoint f g⁻¹ ↔ Disjoint f g := by
  

Proof state:
α : Type u_1
f g h : Perm α
⊢ Disjoint f g⁻¹ ↔ Disjoint f g

Next tactic:
rw [disjoint_comm, disjoint_inv_left_iff, disjoint_comm]
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by 

Proof state:
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
⊢ (f * g) x = x ∨ h x = x

Next tactic:
cases H1 x
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> 

Proof state:
case inl
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝ : f x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
cases H2 x
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> 

Proof state:
case inr
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝ : h x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
cases H2 x
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> cases H2 x <;> 

Proof state:
case inl.inl
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝¹ : f x = x
h✝ : g x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
simp [*]
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> cases H2 x <;> 

Proof state:
case inl.inr
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝¹ : f x = x
h✝ : h x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
simp [*]
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> cases H2 x <;> 

Proof state:
case inr.inl
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝¹ : h x = x
h✝ : g x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
simp [*]
theorem Disjoint.mul_left (H1 : Disjoint f h) (H2 : Disjoint g h) : Disjoint (f * g) h := fun x =>
  by cases H1 x <;> cases H2 x <;> 

Proof state:
case inr.inr
α : Type u_1
f g h : Perm α
H1 : Disjoint f h
H2 : Disjoint g h
x : α
h✝¹ h✝ : h x = x
⊢ (f * g) x = x ∨ h x = x

Next tactic:
simp [*]
theorem Disjoint.mul_right (H1 : Disjoint f g) (H2 : Disjoint f h) : Disjoint f (g * h) := by
  

Proof state:
α : Type u_1
f g h : Perm α
H1 : Disjoint f g
H2 : Disjoint f h
⊢ Disjoint f (g * h)

Next tactic:
rw [disjoint_comm]
theorem Disjoint.mul_right (H1 : Disjoint f g) (H2 : Disjoint f h) : Disjoint f (g * h) := by
  rw [disjoint_comm]
  

Proof state:
α : Type u_1
f g h : Perm α
H1 : Disjoint f g
H2 : Disjoint f h
⊢ Disjoint (g * h) f

Next tactic:
exact H1.symm.mul_left H2.symm
theorem disjoint_conj (h : Perm α) : Disjoint (h * f * h⁻¹) (h * g * h⁻¹) ↔ Disjoint f g :=
  (h⁻¹).forall_congr fun {_} ↦ by 

Proof state:
α : Type u_1
f g h✝ h : Perm α
x✝ : α
⊢ (h * f * h⁻¹) x✝ = x✝ ∨ (h * g * h⁻¹) x✝ = x✝ ↔ f (h⁻¹ x✝) = h⁻¹ x✝ ∨ g (h⁻¹ x✝) = h⁻¹ x✝

Next tactic:
simp only [mul_apply, eq_inv_iff_eq]
theorem disjoint_prod_right (l : List (Perm α)) (h : ∀ g ∈ l, Disjoint f g) :
    Disjoint f l.prod := by
  

Proof state:
α : Type u_1
f g h✝ : Perm α
l : List (Perm α)
h : ∀ g ∈ l, Disjoint f g
⊢ Disjoint f (List.prod l)

Next tactic:
induction' l with g l ih
theorem disjoint_prod_right (l : List (Perm α)) (h : ∀ g ∈ l, Disjoint f g) :
    Disjoint f l.prod := by
  induction' l with g l ih
  · 

Proof state:
case nil
α : Type u_1
f g h✝ : Perm α
h : ∀ g ∈ [], Disjoint f g
⊢ Disjoint f (List.prod [])

Next tactic:
exact disjoint_one_right _
theorem disjoint_prod_right (l : List (Perm α)) (h : ∀ g ∈ l, Disjoint f g) :
    Disjoint f l.prod := by
  induction' l with g l ih
  · exact disjoint_one_right _
  · 

Proof state:
case cons
α : Type u_1
f g✝ h✝ g : Perm α
l : List (Perm α)
ih : (∀ g ∈ l, Disjoint f g) → Disjoint f (List.prod l)
h : ∀ g_1 ∈ g :: l, Disjoint f g_1
⊢ Disjoint f (List.prod (g :: l))

Next tactic:
rw [List.prod_cons]
theorem disjoint_prod_right (l : List (Perm α)) (h : ∀ g ∈ l, Disjoint f g) :
    Disjoint f l.prod := by
  induction' l with g l ih
  · exact disjoint_one_right _
  · rw [List.prod_cons]
    

Proof state:
case cons
α : Type u_1
f g✝ h✝ g : Perm α
l : List (Perm α)
ih : (∀ g ∈ l, Disjoint f g) → Disjoint f (List.prod l)
h : ∀ g_1 ∈ g :: l, Disjoint f g_1
⊢ Disjoint f (g * List.prod l)

Next tactic:
exact (h _ (List.mem_cons_self _ _)).mul_right (ih fun g hg => h g (List.mem_cons_of_mem _ hg))
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
⊢ List.Nodup l

Next tactic:
refine' List.Pairwise.imp_of_mem _ h2
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  refine' List.Pairwise.imp_of_mem _ h2
  

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
⊢ ∀ {a b : Perm α}, a ∈ l → b ∈ l → Disjoint a b → a ≠ b

Next tactic:
intro τ σ h_mem _ h_disjoint _
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  refine' List.Pairwise.imp_of_mem _ h2
  intro τ σ h_mem _ h_disjoint _
  

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
τ σ : Perm α
h_mem : τ ∈ l
a✝¹ : σ ∈ l
h_disjoint : Disjoint τ σ
a✝ : τ = σ
⊢ False

Next tactic:
subst τ
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  refine' List.Pairwise.imp_of_mem _ h2
  intro τ σ h_mem _ h_disjoint _
  subst τ
  

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
σ : Perm α
a✝ h_mem : σ ∈ l
h_disjoint : Disjoint σ σ
⊢ False

Next tactic:
suffices (σ : Perm α) = 1 by
    rw [this] at h_mem
    exact h1 h_mem
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  refine' List.Pairwise.imp_of_mem _ h2
  intro τ σ h_mem _ h_disjoint _
  subst τ
  suffices (σ : Perm α) = 1 by
    

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
σ : Perm α
a✝ h_mem : σ ∈ l
h_disjoint : Disjoint σ σ
this : σ = 1
⊢ False

Next tactic:
rw [this] at h_mem
theorem nodup_of_pairwise_disjoint {l : List (Perm α)} (h1 : (1 : Perm α) ∉ l)
    (h2 : l.Pairwise Disjoint) : l.Nodup := by
  refine' List.Pairwise.imp_of_mem _ h2
  intro τ σ h_mem _ h_disjoint _
  subst τ
  suffices (σ : Perm α) = 1 by
    rw [this] at h_mem
    

Proof state:
α : Type u_1
f g h : Perm α
l : List (Perm α)
h1 : 1 ∉ l
h2 : List.Pairwise Disjoint l
σ : Perm α
a✝ : σ ∈ l
h_mem : 1 ∈ l
h_disjoint : Disjoint σ σ
this : σ = 1
⊢ False

Next tactic:
exact h1 h_mem