l3lab/ntp-mathlib huggingface dataset:
theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α)
    (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) :
    ∀ x, g₁ x = g₂ x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change g₁ ⟦⟨a, f⟩⟧ = g₂ ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]; 

Proof state:
case mk.mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g₁ g₂ : Fix F → α
h : ∀ (x : F (Fix F)), g₁ <$> x = g₂ <$> x → g₁ (mk x) = g₂ (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), g₁ (Quot.mk Setoid.r (f a)) = g₂ (Quot.mk Setoid.r (f a))
⊢ g₁ (mk (abs { fst := a, snd := fun x => ⟦f x⟧ })) = g₂ (mk (abs { fst := a, snd := fun x => ⟦f x⟧ }))

Next tactic:
apply h
theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α)
    (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) :
    ∀ x, g₁ x = g₂ x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change g₁ ⟦⟨a, f⟩⟧ = g₂ ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]; apply h
  

Proof state:
case mk.mk.a
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g₁ g₂ : Fix F → α
h : ∀ (x : F (Fix F)), g₁ <$> x = g₂ <$> x → g₁ (mk x) = g₂ (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), g₁ (Quot.mk Setoid.r (f a)) = g₂ (Quot.mk Setoid.r (f a))
⊢ g₁ <$> abs { fst := a, snd := fun x => ⟦f x⟧ } = g₂ <$> abs { fst := a, snd := fun x => ⟦f x⟧ }

Next tactic:
rw [← abs_map, ← abs_map, PFunctor.map_eq, PFunctor.map_eq]
theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α)
    (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) :
    ∀ x, g₁ x = g₂ x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change g₁ ⟦⟨a, f⟩⟧ = g₂ ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]; apply h
  rw [← abs_map, ← abs_map, PFunctor.map_eq, PFunctor.map_eq]
  

Proof state:
case mk.mk.a
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g₁ g₂ : Fix F → α
h : ∀ (x : F (Fix F)), g₁ <$> x = g₂ <$> x → g₁ (mk x) = g₂ (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), g₁ (Quot.mk Setoid.r (f a)) = g₂ (Quot.mk Setoid.r (f a))
⊢ abs { fst := a, snd := g₁ ∘ fun x => ⟦f x⟧ } = abs { fst := a, snd := g₂ ∘ fun x => ⟦f x⟧ }

Next tactic:
congr with x
theorem Fix.ind_rec {α : Type u} (g₁ g₂ : Fix F → α)
    (h : ∀ x : F (Fix F), g₁ <$> x = g₂ <$> x → g₁ (Fix.mk x) = g₂ (Fix.mk x)) :
    ∀ x, g₁ x = g₂ x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change g₁ ⟦⟨a, f⟩⟧ = g₂ ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]; apply h
  rw [← abs_map, ← abs_map, PFunctor.map_eq, PFunctor.map_eq]
  congr with x
  

Proof state:
case mk.mk.a.e_a.e_snd.h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g₁ g₂ : Fix F → α
h : ∀ (x : F (Fix F)), g₁ <$> x = g₂ <$> x → g₁ (mk x) = g₂ (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), g₁ (Quot.mk Setoid.r (f a)) = g₂ (Quot.mk Setoid.r (f a))
x : PFunctor.B (P F) a
⊢ (g₁ ∘ fun x => ⟦f x⟧) x = (g₂ ∘ fun x => ⟦f x⟧) x

Next tactic:
apply ih
theorem Fix.rec_unique {α : Type u} (g : F α → α) (h : Fix F → α)
    (hyp : ∀ x, h (Fix.mk x) = g (h <$> x)) : Fix.rec g = h := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : F α → α
h : Fix F → α
hyp : ∀ (x : F (Fix F)), h (mk x) = g (h <$> x)
⊢ rec g = h

Next tactic:
ext x
theorem Fix.rec_unique {α : Type u} (g : F α → α) (h : Fix F → α)
    (hyp : ∀ x, h (Fix.mk x) = g (h <$> x)) : Fix.rec g = h := by
  ext x
  

Proof state:
case h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : F α → α
h : Fix F → α
hyp : ∀ (x : F (Fix F)), h (mk x) = g (h <$> x)
x : Fix F
⊢ rec g x = h x

Next tactic:
apply Fix.ind_rec
theorem Fix.rec_unique {α : Type u} (g : F α → α) (h : Fix F → α)
    (hyp : ∀ x, h (Fix.mk x) = g (h <$> x)) : Fix.rec g = h := by
  ext x
  apply Fix.ind_rec
  

Proof state:
case h.h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : F α → α
h : Fix F → α
hyp : ∀ (x : F (Fix F)), h (mk x) = g (h <$> x)
x : Fix F
⊢ ∀ (x : F (Fix F)), rec g <$> x = (fun x => h x) <$> x → rec g (mk x) = h (mk x)

Next tactic:
intro x hyp'
theorem Fix.rec_unique {α : Type u} (g : F α → α) (h : Fix F → α)
    (hyp : ∀ x, h (Fix.mk x) = g (h <$> x)) : Fix.rec g = h := by
  ext x
  apply Fix.ind_rec
  intro x hyp'
  

Proof state:
case h.h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : F α → α
h : Fix F → α
hyp : ∀ (x : F (Fix F)), h (mk x) = g (h <$> x)
x✝ : Fix F
x : F (Fix F)
hyp' : rec g <$> x = (fun x => h x) <$> x
⊢ rec g (mk x) = h (mk x)

Next tactic:
rw [hyp, ← hyp', Fix.rec_eq]
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : Fix F
⊢ mk (dest x) = x

Next tactic:
change (Fix.mk ∘ Fix.dest) x = id x
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  change (Fix.mk ∘ Fix.dest) x = id x
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : Fix F
⊢ (mk ∘ dest) x = id x

Next tactic:
apply Fix.ind_rec (mk ∘ dest) id
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  change (Fix.mk ∘ Fix.dest) x = id x
  apply Fix.ind_rec (mk ∘ dest) id
  

Proof state:
case h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : Fix F
⊢ ∀ (x : F (Fix F)), (mk ∘ dest) <$> x = id <$> x → (mk ∘ dest) (mk x) = id (mk x)

Next tactic:
intro x
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  change (Fix.mk ∘ Fix.dest) x = id x
  apply Fix.ind_rec (mk ∘ dest) id
  intro x
  

Proof state:
case h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x✝ : Fix F
x : F (Fix F)
⊢ (mk ∘ dest) <$> x = id <$> x → (mk ∘ dest) (mk x) = id (mk x)

Next tactic:
rw [Function.comp_apply, id_eq, Fix.dest, Fix.rec_eq, id_map, comp_map]
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  change (Fix.mk ∘ Fix.dest) x = id x
  apply Fix.ind_rec (mk ∘ dest) id
  intro x
  rw [Function.comp_apply, id_eq, Fix.dest, Fix.rec_eq, id_map, comp_map]
  

Proof state:
case h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x✝ : Fix F
x : F (Fix F)
⊢ mk <$> rec (Functor.map mk) <$> x = x → mk (mk <$> rec (Functor.map mk) <$> x) = mk x

Next tactic:
intro h
theorem Fix.mk_dest (x : Fix F) : Fix.mk (Fix.dest x) = x := by
  change (Fix.mk ∘ Fix.dest) x = id x
  apply Fix.ind_rec (mk ∘ dest) id
  intro x
  rw [Function.comp_apply, id_eq, Fix.dest, Fix.rec_eq, id_map, comp_map]
  intro h
  

Proof state:
case h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x✝ : Fix F
x : F (Fix F)
h : mk <$> rec (Functor.map mk) <$> x = x
⊢ mk (mk <$> rec (Functor.map mk) <$> x) = mk x

Next tactic:
rw [h]
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
⊢ dest (mk x) = x

Next tactic:
unfold Fix.dest
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; 

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
⊢ rec (Functor.map mk) (mk x) = x

Next tactic:
rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
⊢ (mk ∘ dest) <$> x = x

Next tactic:
conv =>
    rhs
    rw [← id_map x]
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  conv =>
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
| (mk ∘ dest) <$> x = x

Next tactic:
rhs
    rw [← id_map x]
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  conv =>
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
| (mk ∘ dest) <$> x = x

Next tactic:
rhs
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  conv =>
    rhs
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
| x

Next tactic:
rw [← id_map x]
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  conv =>
    rhs
    rw [← id_map x]
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x : F (Fix F)
⊢ (mk ∘ dest) <$> x = id <$> x

Next tactic:
congr with x
theorem Fix.dest_mk (x : F (Fix F)) : Fix.dest (Fix.mk x) = x := by
  unfold Fix.dest; rw [Fix.rec_eq, ← Fix.dest, ← comp_map]
  conv =>
    rhs
    rw [← id_map x]
  congr with x
  

Proof state:
case e_a.h
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x✝ : F (Fix F)
x : Fix F
⊢ (mk ∘ dest) x = id x

Next tactic:
apply Fix.mk_dest
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
⊢ ∀ (x : Fix F), p x

Next tactic:
apply Quot.ind
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  

Proof state:
case mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
⊢ ∀ (a : PFunctor.W (P F)), p (Quot.mk Setoid.r a)

Next tactic:
intro x
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  

Proof state:
case mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
x : PFunctor.W (P F)
⊢ p (Quot.mk Setoid.r x)

Next tactic:
induction' x with a f ih
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  

Proof state:
case mk.mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ p (Quot.mk Setoid.r (WType.mk a f))

Next tactic:
change p ⟦⟨a, f⟩⟧
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change p ⟦⟨a, f⟩⟧
  

Proof state:
case mk.mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ p ⟦WType.mk a f⟧

Next tactic:
rw [← Fix.ind_aux a f]
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change p ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]
  

Proof state:
case mk.mk
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ p (mk (abs { fst := a, snd := fun x => ⟦f x⟧ }))

Next tactic:
apply h
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change p ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]
  apply h
  

Proof state:
case mk.mk.a
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ Liftp p (abs { fst := a, snd := fun x => ⟦f x⟧ })

Next tactic:
rw [liftp_iff]
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change p ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]
  apply h
  rw [liftp_iff]
  

Proof state:
case mk.mk.a
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ ∃ a_1 f_1,
    abs { fst := a, snd := fun x => ⟦f x⟧ } = abs { fst := a_1, snd := f_1 } ∧ ∀ (i : PFunctor.B (P F) a_1), p (f_1 i)

Next tactic:
refine' ⟨_, _, rfl, _⟩
theorem Fix.ind (p : Fix F → Prop) (h : ∀ x : F (Fix F), Liftp p x → p (Fix.mk x)) : ∀ x, p x := by
  apply Quot.ind
  intro x
  induction' x with a f ih
  change p ⟦⟨a, f⟩⟧
  rw [← Fix.ind_aux a f]
  apply h
  rw [liftp_iff]
  refine' ⟨_, _, rfl, _⟩
  

Proof state:
case mk.mk.a
F : Type u → Type u
inst✝ : Functor F
q : QPF F
p : Fix F → Prop
h : ∀ (x : F (Fix F)), Liftp p x → p (mk x)
a : (P F).A
f : PFunctor.B (P F) a → WType (P F).B
ih : ∀ (a : PFunctor.B (P F) a), p (Quot.mk Setoid.r (f a))
⊢ ∀ (i : PFunctor.B (P F) a), p ⟦f i⟧

Next tactic:
convert ih
theorem corecF_eq {α : Type _} (g : α → F α) (x : α) :
    PFunctor.M.dest (corecF g x) = q.P.map (corecF g) (repr (g x)) := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
⊢ PFunctor.M.dest (corecF g x) = PFunctor.map (P F) (corecF g) (repr (g x))

Next tactic:
rw [corecF, PFunctor.M.dest_corec]
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
⊢ ∀ (a b : PFunctor.M (P F)),
    Mcongr a b →
      (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) a = (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) b

Next tactic:
rintro x y ⟨r, pr, rxy⟩
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      

Proof state:
case intro.intro
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
⊢ (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) x = (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) y

Next tactic:
dsimp
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      

Proof state:
case intro.intro
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
⊢ Quot.mk Mcongr <$> abs (PFunctor.M.dest x) = Quot.mk Mcongr <$> abs (PFunctor.M.dest y)

Next tactic:
have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
⊢ ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y

Next tactic:
intro x y h
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x✝ y✝ : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x✝ y✝
x y : PFunctor.M (P F)
h : r x y
⊢ Mcongr x y

Next tactic:
exact ⟨r, pr, h⟩
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
      

Proof state:
case intro.intro
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
this : ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y
⊢ Quot.mk Mcongr <$> abs (PFunctor.M.dest x) = Quot.mk Mcongr <$> abs (PFunctor.M.dest y)

Next tactic:
rw [← Quot.factor_mk_eq _ _ this]
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
      rw [← Quot.factor_mk_eq _ _ this]
      

Proof state:
case intro.intro
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
this : ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y
⊢ (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest x) =
    (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest y)

Next tactic:
conv =>
        lhs
        rw [comp_map, ← abs_map, pr rxy, abs_map, ← comp_map]
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
      rw [← Quot.factor_mk_eq _ _ this]
      conv =>
        

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
this : ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y
| (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest x) =
    (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest y)

Next tactic:
lhs
        rw [comp_map, ← abs_map, pr rxy, abs_map, ← comp_map]
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
      rw [← Quot.factor_mk_eq _ _ this]
      conv =>
        

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
this : ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y
| (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest x) =
    (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest y)

Next tactic:
lhs
/-- destructor for type defined by `Cofix` -/
def Cofix.dest : Cofix F → F (Cofix F) :=
  Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
    (by
      rintro x y ⟨r, pr, rxy⟩
      dsimp
      have : ∀ x y, r x y → Mcongr x y := by
        intro x y h
        exact ⟨r, pr, h⟩
      rw [← Quot.factor_mk_eq _ _ this]
      conv =>
        lhs
        

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
x y : PFunctor.M (P F)
r : PFunctor.M (P F) → PFunctor.M (P F) → Prop
pr : IsPrecongr r
rxy : r x y
this : ∀ (x y : PFunctor.M (P F)), r x y → Mcongr x y
| (Quot.factor (fun x y => r x y) (fun x y => Mcongr x y) this ∘ Quot.mk fun x y => r x y) <$> abs (PFunctor.M.dest x)

Next tactic:
rw [comp_map, ← abs_map, pr rxy, abs_map, ← comp_map]
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
⊢ dest (corec g x) = corec g <$> g x

Next tactic:
conv =>
    lhs
    rw [Cofix.dest, Cofix.corec];
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
| dest (corec g x) = corec g <$> g x

Next tactic:
lhs
    rw [Cofix.dest, Cofix.corec];
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
| dest (corec g x) = corec g <$> g x

Next tactic:
lhs
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    lhs
    

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
| dest (corec g x)

Next tactic:
rw [Cofix.dest, Cofix.corec]
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    lhs
    rw [Cofix.dest, Cofix.corec];
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
⊢ Quot.lift (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x))
      (_ :
        ∀ (x y : PFunctor.M (P F)),
          Mcongr x y →
            (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) x =
              (fun x => Quot.mk Mcongr <$> abs (PFunctor.M.dest x)) y)
      (Quot.mk Mcongr (corecF g x)) =
    corec g <$> g x

Next tactic:
dsimp
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    lhs
    rw [Cofix.dest, Cofix.corec];
  dsimp
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
⊢ Quot.mk Mcongr <$> abs (PFunctor.M.dest (corecF g x)) = corec g <$> g x

Next tactic:
rw [corecF_eq, abs_map, abs_repr, ← comp_map]
theorem Cofix.dest_corec {α : Type u} (g : α → F α) (x : α) :
    Cofix.dest (Cofix.corec g x) = Cofix.corec g <$> g x := by
  conv =>
    lhs
    rw [Cofix.dest, Cofix.corec];
  dsimp
  rw [corecF_eq, abs_map, abs_repr, ← comp_map]; 

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
α : Type u
g : α → F α
x : α
⊢ (Quot.mk Mcongr ∘ corecF g) <$> g x = corec g <$> g x

Next tactic:
rfl
private theorem Cofix.bisim_aux (r : Cofix F → Cofix F → Prop) (h' : ∀ x, r x x)
    (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) :
    ∀ x y, r x y → x = y := by
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
r : Cofix F → Cofix F → Prop
h' : ∀ (x : Cofix F), r x x
h : ∀ (x y : Cofix F), r x y → Quot.mk r <$> dest x = Quot.mk r <$> dest y
⊢ ∀ (x y : Cofix F), r x y → x = y

Next tactic:
intro x
private theorem Cofix.bisim_aux (r : Cofix F → Cofix F → Prop) (h' : ∀ x, r x x)
    (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) :
    ∀ x y, r x y → x = y := by
  intro x
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
r : Cofix F → Cofix F → Prop
h' : ∀ (x : Cofix F), r x x
h : ∀ (x y : Cofix F), r x y → Quot.mk r <$> dest x = Quot.mk r <$> dest y
x : Cofix F
⊢ ∀ (y : Cofix F), r x y → x = y

Next tactic:
apply Quot.inductionOn (motive := _) x
private theorem Cofix.bisim_aux (r : Cofix F → Cofix F → Prop) (h' : ∀ x, r x x)
    (h : ∀ x y, r x y → Quot.mk r <$> Cofix.dest x = Quot.mk r <$> Cofix.dest y) :
    ∀ x y, r x y → x = y := by
  intro x
  apply Quot.inductionOn (motive := _) x
  

Proof state:
F : Type u → Type u
inst✝ : Functor F
q : QPF F
r : Cofix F → Cofix F → Prop
h' : ∀ (x : Cofix F), r x x
h : ∀ (x y : Cofix F), r x y → Quot.mk r <$> dest x = Quot.mk r <$> dest y
x : Cofix F
⊢ ∀ (a : PFunctor.M (P F)) (y : Cofix F), r (Quot.mk Mcongr a) y → Quot.mk Mcongr a = y

Next tactic:
clear x