l3lab/ntp-mathlib huggingface dataset:
/-- In a second countable space, the set of points where a monotone function is not continuous
is at most countable. -/
theorem countable_not_continuousAt [SecondCountableTopology β] :
    Set.Countable { x | ¬ContinuousAt f x } := by
  apply
    (hf.countable_not_continuousWithinAt_Ioi.union hf.countable_not_continuousWithinAt_Iio).mono
      _
  refine' compl_subset_compl.1 _
  simp only [compl_union]
  rintro x ⟨hx, h'x⟩
  simp only [mem_setOf_eq, Classical.not_not, mem_compl_iff] at hx h'x ⊢
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝⁶ : LinearOrder α
inst✝⁵ : ConditionallyCompleteLinearOrder β
inst✝⁴ : TopologicalSpace β
inst✝³ : OrderTopology β
f : α → β
hf : Monotone f
x✝ y : α
inst✝² : TopologicalSpace α
inst✝¹ : OrderTopology α
inst✝ : SecondCountableTopology β
x : α
hx : ContinuousWithinAt f (Ioi x) x
h'x : ContinuousWithinAt f (Iio x) x
⊢ ContinuousAt f x

Next tactic:
exact continuousAt_iff_continuous_left'_right'.2 ⟨h'x, hx⟩
@[simp]
theorem W.dest_mk (p : P (W P)) : W.dest (W.mk p) = p := by 

Proof state:
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
p : ↑P (W P)
⊢ dest (mk p) = p

Next tactic:
cases p
@[simp]
theorem W.dest_mk (p : P (W P)) : W.dest (W.mk p) = p := by cases p; 

Proof state:
case mk
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
fst✝ : P.A
snd✝ : B P fst✝ → W P
⊢ dest (mk { fst := fst✝, snd := snd✝ }) = { fst := fst✝, snd := snd✝ }

Next tactic:
rfl
@[simp]
theorem W.mk_dest (p : W P) : W.mk (W.dest p) = p := by 

Proof state:
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
p : W P
⊢ mk (dest p) = p

Next tactic:
cases p
@[simp]
theorem W.mk_dest (p : W P) : W.mk (W.dest p) = p := by cases p; 

Proof state:
case mk
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
a✝ : P.A
f✝ : B P a✝ → WType P.B
⊢ mk (dest (WType.mk a✝ f✝)) = WType.mk a✝ f✝

Next tactic:
rfl
@[simp]
theorem fst_map (x : P α) (f : α → β) : (P.map f x).1 = x.1 := by 

Proof state:
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
x : ↑P α
f : α → β
⊢ (map P f x).fst = x.fst

Next tactic:
cases x
@[simp]
theorem fst_map (x : P α) (f : α → β) : (P.map f x).1 = x.1 := by cases x; 

Proof state:
case mk
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
f : α → β
fst✝ : P.A
snd✝ : B P fst✝ → α
⊢ (map P f { fst := fst✝, snd := snd✝ }).fst = { fst := fst✝, snd := snd✝ }.fst

Next tactic:
rfl
@[simp]
theorem iget_map [DecidableEq P.A] [Inhabited α] [Inhabited β] (x : P α)
    (f : α → β) (i : P.Idx) (h : i.1 = x.1) : (P.map f x).iget i = f (x.iget i) := by
  

Proof state:
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
inst✝² : DecidableEq P.A
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x : ↑P α
f : α → β
i : Idx P
h : i.fst = x.fst
⊢ Obj.iget (map P f x) i = f (Obj.iget x i)

Next tactic:
simp only [Obj.iget, fst_map, *, dif_pos, eq_self_iff_true]
@[simp]
theorem iget_map [DecidableEq P.A] [Inhabited α] [Inhabited β] (x : P α)
    (f : α → β) (i : P.Idx) (h : i.1 = x.1) : (P.map f x).iget i = f (x.iget i) := by
  simp only [Obj.iget, fst_map, *, dif_pos, eq_self_iff_true]
  

Proof state:
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
inst✝² : DecidableEq P.A
inst✝¹ : Inhabited α
inst✝ : Inhabited β
x : ↑P α
f : α → β
i : Idx P
h : i.fst = x.fst
⊢ Sigma.snd (map P f x) (cast (_ : B P i.fst = B P (map P f x).fst) i.snd) =
    f (Sigma.snd x (cast (_ : B P i.fst = B P x.fst) i.snd))

Next tactic:
cases x
@[simp]
theorem iget_map [DecidableEq P.A] [Inhabited α] [Inhabited β] (x : P α)
    (f : α → β) (i : P.Idx) (h : i.1 = x.1) : (P.map f x).iget i = f (x.iget i) := by
  simp only [Obj.iget, fst_map, *, dif_pos, eq_self_iff_true]
  cases x
  

Proof state:
case mk
P : PFunctor.{u}
α : Type v₁
β : Type v₂
γ : Type v₃
inst✝² : DecidableEq P.A
inst✝¹ : Inhabited α
inst✝ : Inhabited β
f : α → β
i : Idx P
fst✝ : P.A
snd✝ : B P fst✝ → α
h : i.fst = { fst := fst✝, snd := snd✝ }.fst
⊢ Sigma.snd (map P f { fst := fst✝, snd := snd✝ })
      (cast (_ : B P i.fst = B P (map P f { fst := fst✝, snd := snd✝ }).fst) i.snd) =
    f (Sigma.snd { fst := fst✝, snd := snd✝ } (cast (_ : B P i.fst = B P { fst := fst✝, snd := snd✝ }.fst) i.snd))

Next tactic:
rfl
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  

Proof state:
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
⊢ Liftp p x ↔ ∃ a f, x = { fst := a, snd := f } ∧ ∀ (i : B P a), p (f i)

Next tactic:
constructor
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · 

Proof state:
case mp
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
⊢ Liftp p x → ∃ a f, x = { fst := a, snd := f } ∧ ∀ (i : B P a), p (f i)

Next tactic:
rintro ⟨y, hy⟩
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    

Proof state:
case mp.intro
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
y : ↑P (Subtype p)
hy : Subtype.val <$> y = x
⊢ ∃ a f, x = { fst := a, snd := f } ∧ ∀ (i : B P a), p (f i)

Next tactic:
cases' h : y with a f
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    

Proof state:
case mp.intro.mk
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
y : ↑P (Subtype p)
hy : Subtype.val <$> y = x
a : P.A
f : B P a → Subtype p
h : y = { fst := a, snd := f }
⊢ ∃ a f, x = { fst := a, snd := f } ∧ ∀ (i : B P a), p (f i)

Next tactic:
refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    

Proof state:
case mp.intro.mk
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
y : ↑P (Subtype p)
hy : Subtype.val <$> y = x
a : P.A
f : B P a → Subtype p
h : y = { fst := a, snd := f }
⊢ x = { fst := a, snd := fun i => ↑(f i) }

Next tactic:
rw [← hy, h, map_eq_map, PFunctor.map_eq]
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    rw [← hy, h, map_eq_map, PFunctor.map_eq]
    

Proof state:
case mp.intro.mk
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
y : ↑P (Subtype p)
hy : Subtype.val <$> y = x
a : P.A
f : B P a → Subtype p
h : y = { fst := a, snd := f }
⊢ { fst := a, snd := Subtype.val ∘ f } = { fst := a, snd := fun i => ↑(f i) }

Next tactic:
congr
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    rw [← hy, h, map_eq_map, PFunctor.map_eq]
    congr
  

Proof state:
case mpr
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
⊢ (∃ a f, x = { fst := a, snd := f } ∧ ∀ (i : B P a), p (f i)) → Liftp p x

Next tactic:
rintro ⟨a, f, xeq, pf⟩
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    rw [← hy, h, map_eq_map, PFunctor.map_eq]
    congr
  rintro ⟨a, f, xeq, pf⟩
  

Proof state:
case mpr.intro.intro.intro
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
a : P.A
f : B P a → α
xeq : x = { fst := a, snd := f }
pf : ∀ (i : B P a), p (f i)
⊢ Liftp p x

Next tactic:
use ⟨a, fun i => ⟨f i, pf i⟩⟩
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    rw [← hy, h, map_eq_map, PFunctor.map_eq]
    congr
  rintro ⟨a, f, xeq, pf⟩
  use ⟨a, fun i => ⟨f i, pf i⟩⟩
  

Proof state:
case h
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
a : P.A
f : B P a → α
xeq : x = { fst := a, snd := f }
pf : ∀ (i : B P a), p (f i)
⊢ Subtype.val <$> { fst := a, snd := fun i => { val := f i, property := (_ : p (f i)) } } = x

Next tactic:
rw [xeq]
theorem liftp_iff {α : Type u} (p : α → Prop) (x : P α) :
    Liftp p x ↔ ∃ a f, x = ⟨a, f⟩ ∧ ∀ i, p (f i) := by
  constructor
  · rintro ⟨y, hy⟩
    cases' h : y with a f
    refine' ⟨a, fun i => (f i).val, _, fun i => (f i).property⟩
    rw [← hy, h, map_eq_map, PFunctor.map_eq]
    congr
  rintro ⟨a, f, xeq, pf⟩
  use ⟨a, fun i => ⟨f i, pf i⟩⟩
  rw [xeq]; 

Proof state:
case h
P : PFunctor.{u}
α : Type u
p : α → Prop
x : ↑P α
a : P.A
f : B P a → α
xeq : x = { fst := a, snd := f }
pf : ∀ (i : B P a), p (f i)
⊢ Subtype.val <$> { fst := a, snd := fun i => { val := f i, property := (_ : p (f i)) } } = { fst := a, snd := f }

Next tactic:
rfl
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  

Proof state:
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
⊢ Liftp p { fst := a, snd := f } ↔ ∀ (i : B P a), p (f i)

Next tactic:
simp only [liftp_iff, Sigma.mk.inj_iff]
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; 

Proof state:
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
⊢ (∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)) ↔ ∀ (i : B P a), p (f i)

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> 

Proof state:
case mp
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
⊢ (∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)) → ∀ (i : B P a), p (f i)

Next tactic:
intro h
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> 

Proof state:
case mpr
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
⊢ (∀ (i : B P a), p (f i)) → ∃ a_2 f_1, { fst := a, snd := f } = { fst := a_2, snd := f_1 } ∧ ∀ (i : B P a_2), p (f_1 i)

Next tactic:
intro h
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · 

Proof state:
case mp
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
rcases h with ⟨a', f', heq, h'⟩
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    

Proof state:
case mp.intro.intro.intro
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
a' : P.A
f' : B P a' → α
heq : { fst := a, snd := f } = { fst := a', snd := f' }
h' : ∀ (i : B P a'), p (f' i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
cases heq
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    

Proof state:
case mp.intro.intro.intro.refl
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h' : ∀ (i : B P a), p (f i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  

Proof state:
case mpr
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)

Next tactic:
repeat' first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' 

Proof state:
case mpr
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)

Next tactic:
first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |

Proof state:
case mpr
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∃ a_1 f_1, { fst := a, snd := f } = { fst := a_1, snd := f_1 } ∧ ∀ (i : B P a_1), p (f_1 i)

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' 

Proof state:
case mpr.h
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∃ f_1, { fst := a, snd := f } = { fst := ?mpr.w, snd := f_1 } ∧ ∀ (i : B P ?mpr.w), p (f_1 i)

Next tactic:
first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |

Proof state:
case mpr.h
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∃ f_1, { fst := a, snd := f } = { fst := ?mpr.w, snd := f_1 } ∧ ∀ (i : B P ?mpr.w), p (f_1 i)

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' 

Proof state:
case mpr.h.h
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ { fst := a, snd := f } = { fst := ?mpr.w, snd := ?mpr.h.w } ∧ ∀ (i : B P ?mpr.w), p (?mpr.h.w i)

Next tactic:
first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |

Proof state:
case mpr.h.h
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ { fst := a, snd := f } = { fst := ?mpr.w, snd := ?mpr.h.w } ∧ ∀ (i : B P ?mpr.w), p (?mpr.h.w i)

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' 

Proof state:
case mpr.h.h.left
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ { fst := a, snd := f } = { fst := ?mpr.w, snd := ?mpr.h.w }

Next tactic:
first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |

Proof state:
case mpr.h.h.left
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ { fst := a, snd := f } = { fst := ?mpr.w, snd := ?mpr.h.w }

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' 

Proof state:
case mpr.h.h.right
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
first |constructor|assumption
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |

Proof state:
case mpr.h.h.right
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
constructor
theorem liftp_iff' {α : Type u} (p : α → Prop) (a : P.A) (f : P.B a → α) :
    @Liftp.{u} P.Obj _ α p ⟨a, f⟩ ↔ ∀ i, p (f i) := by
  simp only [liftp_iff, Sigma.mk.inj_iff]; constructor <;> intro h
  · rcases h with ⟨a', f', heq, h'⟩
    cases heq
    assumption
  repeat' first |constructor|

Proof state:
case mpr.h.h.right
P : PFunctor.{u}
α : Type u
p : α → Prop
a : P.A
f : B P a → α
h : ∀ (i : B P a), p (f i)
⊢ ∀ (i : B P a), p (f i)

Next tactic:
assumption
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  

Proof state:
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
⊢ Liftr r x y ↔ ∃ a f₀ f₁, x = { fst := a, snd := f₀ } ∧ y = { fst := a, snd := f₁ } ∧ ∀ (i : B P a), r (f₀ i) (f₁ i)

Next tactic:
constructor
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · 

Proof state:
case mp
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
⊢ Liftr r x y → ∃ a f₀ f₁, x = { fst := a, snd := f₀ } ∧ y = { fst := a, snd := f₁ } ∧ ∀ (i : B P a), r (f₀ i) (f₁ i)

Next tactic:
rintro ⟨u, xeq, yeq⟩
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    

Proof state:
case mp.intro.intro
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
⊢ ∃ a f₀ f₁, x = { fst := a, snd := f₀ } ∧ y = { fst := a, snd := f₁ } ∧ ∀ (i : B P a), r (f₀ i) (f₁ i)

Next tactic:
cases' h : u with a f
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    

Proof state:
case mp.intro.intro.mk
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ ∃ a f₀ f₁, x = { fst := a, snd := f₀ } ∧ y = { fst := a, snd := f₁ } ∧ ∀ (i : B P a), r (f₀ i) (f₁ i)

Next tactic:
use a, fun i => (f i).val.fst, fun i => (f i).val.snd
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    

Proof state:
case h
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ x = { fst := a, snd := fun i => (↑(f i)).1 } ∧
    y = { fst := a, snd := fun i => (↑(f i)).2 } ∧ ∀ (i : B P a), r (↑(f i)).1 (↑(f i)).2

Next tactic:
constructor
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    constructor
    · 

Proof state:
case h.left
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ x = { fst := a, snd := fun i => (↑(f i)).1 }

Next tactic:
rw [← xeq, h]
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    constructor
    · rw [← xeq, h]
      

Proof state:
case h.left
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ (fun t => (↑t).1) <$> { fst := a, snd := f } = { fst := a, snd := fun i => (↑(f i)).1 }

Next tactic:
rfl
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    constructor
    · rw [← xeq, h]
      rfl
    

Proof state:
case h.right
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ y = { fst := a, snd := fun i => (↑(f i)).2 } ∧ ∀ (i : B P a), r (↑(f i)).1 (↑(f i)).2

Next tactic:
constructor
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    constructor
    · rw [← xeq, h]
      rfl
    constructor
    · 

Proof state:
case h.right.left
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ y = { fst := a, snd := fun i => (↑(f i)).2 }

Next tactic:
rw [← yeq, h]
theorem liftr_iff {α : Type u} (r : α → α → Prop) (x y : P α) :
    Liftr r x y ↔ ∃ a f₀ f₁, x = ⟨a, f₀⟩ ∧ y = ⟨a, f₁⟩ ∧ ∀ i, r (f₀ i) (f₁ i) := by
  constructor
  · rintro ⟨u, xeq, yeq⟩
    cases' h : u with a f
    use a, fun i => (f i).val.fst, fun i => (f i).val.snd
    constructor
    · rw [← xeq, h]
      rfl
    constructor
    · rw [← yeq, h]
      

Proof state:
case h.right.left
P : PFunctor.{u}
α : Type u
r : α → α → Prop
x y : ↑P α
u : ↑P { p // r p.1 p.2 }
xeq : (fun t => (↑t).1) <$> u = x
yeq : (fun t => (↑t).2) <$> u = y
a : P.A
f : B P a → { p // r p.1 p.2 }
h : u = { fst := a, snd := f }
⊢ (fun t => (↑t).2) <$> { fst := a, snd := f } = { fst := a, snd := fun i => (↑(f i)).2 }

Next tactic:
rfl