l3lab/ntp-mathlib huggingface dataset:
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; 

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
h₂ : M.mk { fst := a, snd := f₂ } = M.mk { fst := a, snd := f₂ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
⊢ (CofixA.intro a fun j => MIntl.approx (f₂ j) (n + 1)) = CofixA.intro a fun j => MIntl.approx (f₁ j) (n + 1)

Next tactic:
clear h₂
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
⊢ (CofixA.intro a fun j => MIntl.approx (f₂ j) (n + 1)) = CofixA.intro a fun j => MIntl.approx (f₁ j) (n + 1)

Next tactic:
congr
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
⊢ (fun j => MIntl.approx (f₂ j) (n + 1)) = fun j => MIntl.approx (f₁ j) (n + 1)

Next tactic:
ext i
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
i : B F a
⊢ MIntl.approx (f₂ i) (n + 1) = MIntl.approx (f₁ i) (n + 1)

Next tactic:
apply n_ih
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · 

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hx
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
i : B F a
⊢ Agree' n ?succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.z (f₂ i)

Next tactic:
solve_by_elim
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · solve_by_elim
    · 

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hy
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
i : B F a
⊢ Agree' n (f₃ i) (f₁ i)

Next tactic:
solve_by_elim
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · solve_by_elim
    · solve_by_elim
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hrec
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
i : B F a
⊢ ∀ (ps : Path F), n = length ps → iselect ps (f₂ i) = iselect ps (f₁ i)

Next tactic:
introv h
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · solve_by_elim
    · solve_by_elim
    introv h
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hrec
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
hrec :
  ∀ (ps : Path F),
    succ n = length ps → iselect ps (M.mk { fst := a, snd := f₂ }) = iselect ps (M.mk { fst := a, snd := f₁ })
i : B F a
ps : Path F
h : n = length ps
⊢ iselect ps (f₂ i) = iselect ps (f₁ i)

Next tactic:
specialize hrec (⟨_, i⟩ :: ps) (congr_arg _ h)
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · solve_by_elim
    · solve_by_elim
    introv h
    specialize hrec (⟨_, i⟩ :: ps) (congr_arg _ h)
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hrec
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
i : B F a
ps : Path F
h : n = length ps
hrec :
  iselect ({ fst := a, snd := i } :: ps) (M.mk { fst := a, snd := f₂ }) =
    iselect ({ fst := a, snd := i } :: ps) (M.mk { fst := a, snd := f₁ })
⊢ iselect ps (f₂ i) = iselect ps (f₁ i)

Next tactic:
simp only [iselect_cons] at hrec
theorem ext_aux [Inhabited (M F)] [DecidableEq F.A] {n : ℕ} (x y z : M F) (hx : Agree' n z x)
    (hy : Agree' n z y) (hrec : ∀ ps : Path F, n = ps.length → iselect ps x = iselect ps y) :
    x.approx (n + 1) = y.approx (n + 1) := by
  induction' n with n n_ih generalizing x y z
  · specialize hrec [] rfl
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    simp only [iselect_nil] at hrec
    subst hrec
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq, zero_eq, CofixA.intro.injEq,
                heq_eq_eq, eq_iff_true_of_subsingleton, and_self]
  · cases hx
    cases hy
    induction x using PFunctor.M.casesOn'
    induction y using PFunctor.M.casesOn'
    subst z
    iterate 3 (have := mk_inj ‹_›; cases this)
    rename_i n_ih a f₃ f₂ hAgree₂ _ _ h₂ _ _ f₁ h₁ hAgree₁ clr
    simp only [approx_mk, true_and_iff, eq_self_iff_true, heq_iff_eq]

    have := mk_inj h₁
    cases this; clear h₁
    have := mk_inj h₂
    cases this; clear h₂

    congr
    ext i
    apply n_ih
    · solve_by_elim
    · solve_by_elim
    introv h
    specialize hrec (⟨_, i⟩ :: ps) (congr_arg _ h)
    simp only [iselect_cons] at hrec
    

Proof state:
case succ.step.step.f.f.refl.refl.refl.refl.refl.e_a.h.hrec
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
n_ih✝ : DecidableEq F.A
n : ℕ
n_ih :
  ∀ (x y z : M F),
    Agree' n z x →
      Agree' n z y →
        (∀ (ps : Path F), n = length ps → iselect ps x = iselect ps y) → MIntl.approx x (n + 1) = MIntl.approx y (n + 1)
a : F.A
f₃ f₂ : B F a → M F
hAgree₂ : ∀ (i : B F a), Agree' n (f₃ i) (f₂ i)
f₁ : B F a → M F
hAgree₁ : ∀ (i : B F a), Agree' n (f₃ i) (f₁ i)
clr : M.mk { fst := a, snd := f₃ } = M.mk { fst := a, snd := f₃ }
i : B F a
ps : Path F
h : n = length ps
hrec : iselect ps (f₂ i) = iselect ps (f₁ i)
⊢ iselect ps (f₂ i) = iselect ps (f₁ i)

Next tactic:
exact hrec
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
⊢ x = y

Next tactic:
apply ext'
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; 

Proof state:
case H
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
⊢ ∀ (i : ℕ), MIntl.approx x i = MIntl.approx y i

Next tactic:
intro i
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  

Proof state:
case H
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
⊢ MIntl.approx x i = MIntl.approx y i

Next tactic:
induction' i with i i_ih
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · 

Proof state:
case H.zero
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
⊢ MIntl.approx x zero = MIntl.approx y zero

Next tactic:
cases x.approx 0
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    

Proof state:
case H.zero.continue
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
⊢ CofixA.continue = MIntl.approx y zero

Next tactic:
cases y.approx 0
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    

Proof state:
case H.zero.continue.continue
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
⊢ CofixA.continue = CofixA.continue

Next tactic:
constructor
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · 

Proof state:
case H.succ
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ MIntl.approx x (succ i) = MIntl.approx y (succ i)

Next tactic:
apply ext_aux x y x
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · apply ext_aux x y x
    · 

Proof state:
case H.succ.hx
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ Agree' i x x

Next tactic:
rw [← agree_iff_agree']
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · apply ext_aux x y x
    · rw [← agree_iff_agree']
      

Proof state:
case H.succ.hx
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ Agree (MIntl.approx x i) (MIntl.approx x (i + 1))

Next tactic:
apply x.consistent
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · apply ext_aux x y x
    · rw [← agree_iff_agree']
      apply x.consistent
    · 

Proof state:
case H.succ.hy
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ Agree' i x y

Next tactic:
rw [← agree_iff_agree', i_ih]
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · apply ext_aux x y x
    · rw [← agree_iff_agree']
      apply x.consistent
    · rw [← agree_iff_agree', i_ih]
      

Proof state:
case H.succ.hy
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ Agree (MIntl.approx y i) (MIntl.approx y (i + 1))

Next tactic:
apply y.consistent
theorem ext [Inhabited (M F)] (x y : M F) (H : ∀ ps : Path F, iselect ps x = iselect ps y) :
    x = y := by
  apply ext'; intro i
  induction' i with i i_ih
  · cases x.approx 0
    cases y.approx 0
    constructor
  · apply ext_aux x y x
    · rw [← agree_iff_agree']
      apply x.consistent
    · rw [← agree_iff_agree', i_ih]
      apply y.consistent
    

Proof state:
case H.succ.hrec
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝ : Inhabited (M F)
x y : M F
H : ∀ (ps : Path F), iselect ps x = iselect ps y
i : ℕ
i_ih : MIntl.approx x i = MIntl.approx y i
⊢ ∀ (ps : Path F), i = length ps → iselect ps x = iselect ps y

Next tactic:
introv H'