l3lab/ntp-mathlib huggingface dataset:
/-- The multiplicative indicators of δ-thickenings of a set tend pointwise to the multiplicative
indicator of the set, as δ>0 tends to zero. -/
@[to_additive "The indicators of δ-thickenings of a set tend pointwise to the indicator of the
set, as δ>0 tends to zero."]
lemma tendsto_mulIndicator_thickening_mulIndicator_closure (f : α → β) (E : Set α) :
    Tendsto (fun δ ↦ (Metric.thickening δ E).mulIndicator f) (𝓝[>] 0)
      (𝓝 ((closure E).mulIndicator f)) := by
  rw [tendsto_pi_nhds]
  intro x
  rw [tendsto_congr' (mulIndicator_thickening_eventually_eq_mulIndicator_closure f E x)]
  

Proof state:
α : Type u_1
inst✝² : PseudoEMetricSpace α
β : Type u_2
inst✝¹ : One β
inst✝ : TopologicalSpace β
f : α → β
E : Set α
x : α
⊢ Tendsto (fun x_1 => mulIndicator (closure E) f x) (𝓝[>] 0) (𝓝 (mulIndicator (closure E) f x))

Next tactic:
apply tendsto_const_nhds
/-- The multiplicative indicators of closed δ-thickenings of a set tend pointwise to the
multiplicative indicator of the set, as δ tends to zero. -/
@[to_additive "The indicators of closed δ-thickenings of a set tend pointwise to the indicator
of the set, as δ tends to zero."]
lemma tendsto_mulIndicator_cthickening_mulIndicator_closure (f : α → β) (E : Set α) :
    Tendsto (fun δ ↦ (Metric.cthickening δ E).mulIndicator f) (𝓝 0)
      (𝓝 ((closure E).mulIndicator f)) := by
  

Proof state:
α : Type u_1
inst✝² : PseudoEMetricSpace α
β : Type u_2
inst✝¹ : One β
inst✝ : TopologicalSpace β
f : α → β
E : Set α
⊢ Tendsto (fun δ => mulIndicator (cthickening δ E) f) (𝓝 0) (𝓝 (mulIndicator (closure E) f))

Next tactic:
rw [tendsto_pi_nhds]
/-- The multiplicative indicators of closed δ-thickenings of a set tend pointwise to the
multiplicative indicator of the set, as δ tends to zero. -/
@[to_additive "The indicators of closed δ-thickenings of a set tend pointwise to the indicator
of the set, as δ tends to zero."]
lemma tendsto_mulIndicator_cthickening_mulIndicator_closure (f : α → β) (E : Set α) :
    Tendsto (fun δ ↦ (Metric.cthickening δ E).mulIndicator f) (𝓝 0)
      (𝓝 ((closure E).mulIndicator f)) := by
  rw [tendsto_pi_nhds]
  

Proof state:
α : Type u_1
inst✝² : PseudoEMetricSpace α
β : Type u_2
inst✝¹ : One β
inst✝ : TopologicalSpace β
f : α → β
E : Set α
⊢ ∀ (x : α), Tendsto (fun i => mulIndicator (cthickening i E) f x) (𝓝 0) (𝓝 (mulIndicator (closure E) f x))

Next tactic:
intro x
/-- The multiplicative indicators of closed δ-thickenings of a set tend pointwise to the
multiplicative indicator of the set, as δ tends to zero. -/
@[to_additive "The indicators of closed δ-thickenings of a set tend pointwise to the indicator
of the set, as δ tends to zero."]
lemma tendsto_mulIndicator_cthickening_mulIndicator_closure (f : α → β) (E : Set α) :
    Tendsto (fun δ ↦ (Metric.cthickening δ E).mulIndicator f) (𝓝 0)
      (𝓝 ((closure E).mulIndicator f)) := by
  rw [tendsto_pi_nhds]
  intro x
  

Proof state:
α : Type u_1
inst✝² : PseudoEMetricSpace α
β : Type u_2
inst✝¹ : One β
inst✝ : TopologicalSpace β
f : α → β
E : Set α
x : α
⊢ Tendsto (fun i => mulIndicator (cthickening i E) f x) (𝓝 0) (𝓝 (mulIndicator (closure E) f x))

Next tactic:
rw [tendsto_congr' (mulIndicator_cthickening_eventually_eq_mulIndicator_closure f E x)]
/-- The multiplicative indicators of closed δ-thickenings of a set tend pointwise to the
multiplicative indicator of the set, as δ tends to zero. -/
@[to_additive "The indicators of closed δ-thickenings of a set tend pointwise to the indicator
of the set, as δ tends to zero."]
lemma tendsto_mulIndicator_cthickening_mulIndicator_closure (f : α → β) (E : Set α) :
    Tendsto (fun δ ↦ (Metric.cthickening δ E).mulIndicator f) (𝓝 0)
      (𝓝 ((closure E).mulIndicator f)) := by
  rw [tendsto_pi_nhds]
  intro x
  rw [tendsto_congr' (mulIndicator_cthickening_eventually_eq_mulIndicator_closure f E x)]
  

Proof state:
α : Type u_1
inst✝² : PseudoEMetricSpace α
β : Type u_2
inst✝¹ : One β
inst✝ : TopologicalSpace β
f : α → β
E : Set α
x : α
⊢ Tendsto (fun x_1 => mulIndicator (closure E) f x) (𝓝 0) (𝓝 (mulIndicator (closure E) f x))

Next tactic:
apply tendsto_const_nhds
lemma heq_iff_coe_heq {α β : Sort _} {p : α → Prop} {q : β → Prop} {a : {x // p x}}
    {b : {y // q y}} (h : α = β) (h' : HEq p q) : HEq a b ↔ HEq (a : α) (b : β) := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q✝ : α✝ → Prop
α β : Sort u_4
p : α → Prop
q : β → Prop
a : { x // p x }
b : { y // q y }
h : α = β
h' : HEq p q
⊢ HEq a b ↔ HEq ↑a ↑b

Next tactic:
subst h
lemma heq_iff_coe_heq {α β : Sort _} {p : α → Prop} {q : β → Prop} {a : {x // p x}}
    {b : {y // q y}} (h : α = β) (h' : HEq p q) : HEq a b ↔ HEq (a : α) (b : β) := by
  subst h
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
p✝ q✝ : α✝ → Prop
α : Sort u_4
p : α → Prop
a : { x // p x }
q : α → Prop
b : { y // q y }
h' : HEq p q
⊢ HEq a b ↔ HEq ↑a ↑b

Next tactic:
subst h'
lemma heq_iff_coe_heq {α β : Sort _} {p : α → Prop} {q : β → Prop} {a : {x // p x}}
    {b : {y // q y}} (h : α = β) (h' : HEq p q) : HEq a b ↔ HEq (a : α) (b : β) := by
  subst h
  subst h'
  

Proof state:
α✝ : Sort u_1
β : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_4
p : α → Prop
a b : { y // p y }
⊢ HEq a b ↔ HEq ↑a ↑b

Next tactic:
rw [heq_iff_eq, heq_iff_eq, ext_iff]
@[simp, nolint simpNF]
theorem _root_.exists_subtype_mk_eq_iff {a : Subtype p} {b : α} :
    (∃ h : p b, Subtype.mk b h = a) ↔ b = a := by
  

Proof state:
α : Sort u_1
β : Sort u_2
γ : Sort u_3
p q : α → Prop
a : Subtype p
b : α
⊢ (∃ h, { val := b, property := h } = a) ↔ b = ↑a

Next tactic:
simp only [@eq_comm _ b, exists_eq_subtype_mk_iff, @eq_comm _ _ a]
theorem restrict_apply {α} {β : α → Type*} (f : ∀ x, β x) (p : α → Prop) (x : Subtype p) :
    restrict p f x = f x.1 := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_5
β : α → Type u_4
f : (x : α) → β x
p : α → Prop
x : Subtype p
⊢ restrict p f x = f ↑x

Next tactic:
rfl
theorem surjective_restrict {α} {β : α → Type*} [ne : ∀ a, Nonempty (β a)] (p : α → Prop) :
    Surjective fun f : ∀ x, β x ↦ restrict p f := by
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_5
β : α → Type u_4
ne : ∀ (a : α), Nonempty (β a)
p : α → Prop
⊢ Surjective fun f => restrict p f

Next tactic:
letI := Classical.decPred p
theorem surjective_restrict {α} {β : α → Type*} [ne : ∀ a, Nonempty (β a)] (p : α → Prop) :
    Surjective fun f : ∀ x, β x ↦ restrict p f := by
  letI := Classical.decPred p
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_5
β : α → Type u_4
ne : ∀ (a : α), Nonempty (β a)
p : α → Prop
this : DecidablePred p := Classical.decPred p
⊢ Surjective fun f => restrict p f

Next tactic:
refine' fun f ↦ ⟨fun x ↦ if h : p x then f ⟨x, h⟩ else Nonempty.some (ne x), funext <| _⟩
theorem surjective_restrict {α} {β : α → Type*} [ne : ∀ a, Nonempty (β a)] (p : α → Prop) :
    Surjective fun f : ∀ x, β x ↦ restrict p f := by
  letI := Classical.decPred p
  refine' fun f ↦ ⟨fun x ↦ if h : p x then f ⟨x, h⟩ else Nonempty.some (ne x), funext <| _⟩
  

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_5
β : α → Type u_4
ne : ∀ (a : α), Nonempty (β a)
p : α → Prop
this : DecidablePred p := Classical.decPred p
f : (x : Subtype p) → β ↑x
⊢ ∀ (x : Subtype p),
    (fun f => restrict p f)
        (fun x => if h : p x then f { val := x, property := h } else Nonempty.some (_ : Nonempty (β x))) x =
      f x

Next tactic:
rintro ⟨x, hx⟩
theorem surjective_restrict {α} {β : α → Type*} [ne : ∀ a, Nonempty (β a)] (p : α → Prop) :
    Surjective fun f : ∀ x, β x ↦ restrict p f := by
  letI := Classical.decPred p
  refine' fun f ↦ ⟨fun x ↦ if h : p x then f ⟨x, h⟩ else Nonempty.some (ne x), funext <| _⟩
  rintro ⟨x, hx⟩
  

Proof state:
case mk
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_5
β : α → Type u_4
ne : ∀ (a : α), Nonempty (β a)
p : α → Prop
this : DecidablePred p := Classical.decPred p
f : (x : Subtype p) → β ↑x
x : α
hx : p x
⊢ (fun f => restrict p f)
      (fun x => if h : p x then f { val := x, property := h } else Nonempty.some (_ : Nonempty (β x)))
      { val := x, property := hx } =
    f { val := x, property := hx }

Next tactic:
exact dif_pos hx
theorem coind_injective {α β} {f : α → β} {p : β → Prop} (h : ∀ a, p (f a)) (hf : Injective f) :
    Injective (coind f h) := fun x y hxy ↦ hf <| by 

Proof state:
α✝ : Sort u_1
β✝ : Sort u_2
γ : Sort u_3
p✝ q : α✝ → Prop
α : Sort u_4
β : Sort u_5
f : α → β
p : β → Prop
h : ∀ (a : α), p (f a)
hf : Injective f
x y : α
hxy : coind f h x = coind f h y
⊢ f x = f y

Next tactic:
apply congr_arg Subtype.val hxy
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  

Proof state:
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
⊢ ∃ h, Bijective h

Next tactic:
cases' isEmpty_or_nonempty β with hβ hβ
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · 

Proof state:
case inl
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : IsEmpty β
⊢ ∃ h, Bijective h

Next tactic:
have : IsEmpty α := Function.isEmpty f
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    

Proof state:
case inl
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : IsEmpty β
this : IsEmpty α
⊢ ∃ h, Bijective h

Next tactic:
exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
⊢ ∃ h, Bijective h

Next tactic:
set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
⊢ ∃ h, Bijective h

Next tactic:
set s : Set α := OrderHom.lfp F
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
⊢ ∃ h, Bijective h

Next tactic:
have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
⊢ ∃ h, Bijective h

Next tactic:
have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by 

Proof state:
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
⊢ (g '' (f '' s)ᶜ)ᶜ = sᶜᶜ

Next tactic:
simp [hs]
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
⊢ ∃ h, Bijective h

Next tactic:
set g' := invFun g
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  set g' := invFun g
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
g' : α → β := invFun g
⊢ ∃ h, Bijective h

Next tactic:
have g'g : LeftInverse g' g := leftInverse_invFun hg
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  set g' := invFun g
  have g'g : LeftInverse g' g := leftInverse_invFun hg
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
g' : α → β := invFun g
g'g : LeftInverse g' g
⊢ ∃ h, Bijective h

Next tactic:
have hg'ns : g' '' sᶜ = (f '' s)ᶜ := by rw [← hns, g'g.image_image]
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  set g' := invFun g
  have g'g : LeftInverse g' g := leftInverse_invFun hg
  have hg'ns : g' '' sᶜ = (f '' s)ᶜ := by 

Proof state:
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
g' : α → β := invFun g
g'g : LeftInverse g' g
⊢ g' '' sᶜ = (f '' s)ᶜ

Next tactic:
rw [← hns, g'g.image_image]
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  set g' := invFun g
  have g'g : LeftInverse g' g := leftInverse_invFun hg
  have hg'ns : g' '' sᶜ = (f '' s)ᶜ := by rw [← hns, g'g.image_image]
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
g' : α → β := invFun g
g'g : LeftInverse g' g
hg'ns : g' '' sᶜ = (f '' s)ᶜ
⊢ ∃ h, Bijective h

Next tactic:
set h : α → β := s.piecewise f g'
/-- **The Schröder-Bernstein Theorem**:
Given injections `α → β` and `β → α`, we can get a bijection `α → β`. -/
theorem schroeder_bernstein {f : α → β} {g : β → α} (hf : Function.Injective f)
    (hg : Function.Injective g) : ∃ h : α → β, Bijective h := by
  cases' isEmpty_or_nonempty β with hβ hβ
  · have : IsEmpty α := Function.isEmpty f
    exact ⟨_, ((Equiv.equivEmpty α).trans (Equiv.equivEmpty β).symm).bijective⟩
  set F : Set α →o Set α :=
    { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ
      monotone' := fun s t hst =>
        compl_subset_compl.mpr <| image_subset _ <| compl_subset_compl.mpr <| image_subset _ hst }
  -- Porting note: dot notation `F.lfp` doesn't work here
  set s : Set α := OrderHom.lfp F
  have hs : (g '' (f '' s)ᶜ)ᶜ = s := F.map_lfp
  have hns : g '' (f '' s)ᶜ = sᶜ := compl_injective (by simp [hs])
  set g' := invFun g
  have g'g : LeftInverse g' g := leftInverse_invFun hg
  have hg'ns : g' '' sᶜ = (f '' s)ᶜ := by rw [← hns, g'g.image_image]
  set h : α → β := s.piecewise f g'
  

Proof state:
case inr
α : Type u
β : Type v
f : α → β
g : β → α
hf : Injective f
hg : Injective g
hβ : Nonempty β
F : Set α →o Set α :=
  { toFun := fun s => (g '' (f '' s)ᶜ)ᶜ,
    monotone' := (_ : ∀ (s t : Set α), s ≤ t → (g '' (f '' s)ᶜ)ᶜ ⊆ (g '' (f '' t)ᶜ)ᶜ) }
s : Set α := OrderHom.lfp F
hs : (g '' (f '' s)ᶜ)ᶜ = s
hns : g '' (f '' s)ᶜ = sᶜ
g' : α → β := invFun g
g'g : LeftInverse g' g
hg'ns : g' '' sᶜ = (f '' s)ᶜ
h : α → β := piecewise s f g'
⊢ ∃ h, Bijective h

Next tactic:
have : Surjective h := by rw [← range_iff_surjective, range_piecewise, hg'ns, union_compl_self]