l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem cases_mk {r : M F → Sort*} (x : F (M F)) (f : ∀ x : F (M F), r (M.mk x)) :
    PFunctor.M.cases f (M.mk x) = f x := by
  dsimp only [M.mk, PFunctor.M.cases, dest, head, Approx.sMk, head']
  cases x; dsimp only [Approx.sMk]
  simp only [Eq.mpr]
  

Proof state:
case mk
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
r : M F → Sort u_2
f : (x : ↑F (M F)) → r (M.mk x)
fst✝ : F.A
snd✝ : B F fst✝ → M F
⊢ f
      { fst := fst✝,
        snd := fun i =>
          children
            { approx := Approx.sMk { fst := fst✝, snd := snd✝ },
              consistent := (_ : AllAgree (Approx.sMk { fst := fst✝, snd := snd✝ })) }
            i } =
    f { fst := fst✝, snd := snd✝ }

Next tactic:
apply congrFun
@[simp]
theorem cases_mk {r : M F → Sort*} (x : F (M F)) (f : ∀ x : F (M F), r (M.mk x)) :
    PFunctor.M.cases f (M.mk x) = f x := by
  dsimp only [M.mk, PFunctor.M.cases, dest, head, Approx.sMk, head']
  cases x; dsimp only [Approx.sMk]
  simp only [Eq.mpr]
  apply congrFun
  

Proof state:
case mk.h
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
r : M F → Sort u_2
f : (x : ↑F (M F)) → r (M.mk x)
fst✝ : F.A
snd✝ : B F fst✝ → M F
⊢ f = f

Next tactic:
rfl
theorem isPath_cons {xs : Path F} {a a'} {f : F.B a → M F} {i : F.B a'} :
    IsPath (⟨a', i⟩ :: xs) (M.mk ⟨a, f⟩) → a = a' := by
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a a' : F.A
f : B F a → M F
i : B F a'
⊢ IsPath ({ fst := a', snd := i } :: xs) (M.mk { fst := a, snd := f }) → a = a'

Next tactic:
generalize h : M.mk ⟨a, f⟩ = x
theorem isPath_cons {xs : Path F} {a a'} {f : F.B a → M F} {i : F.B a'} :
    IsPath (⟨a', i⟩ :: xs) (M.mk ⟨a, f⟩) → a = a' := by
  generalize h : M.mk ⟨a, f⟩ = x
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a a' : F.A
f : B F a → M F
i : B F a'
x : M F
h : M.mk { fst := a, snd := f } = x
⊢ IsPath ({ fst := a', snd := i } :: xs) x → a = a'

Next tactic:
rintro (_ | ⟨_, _, _, _, rfl, _⟩)
theorem isPath_cons {xs : Path F} {a a'} {f : F.B a → M F} {i : F.B a'} :
    IsPath (⟨a', i⟩ :: xs) (M.mk ⟨a, f⟩) → a = a' := by
  generalize h : M.mk ⟨a, f⟩ = x
  rintro (_ | ⟨_, _, _, _, rfl, _⟩)
  

Proof state:
case cons
F : PFunctor.{u}
X : Type u_1
f✝¹ : X → ↑F X
xs : Path F
a a' : F.A
f : B F a → M F
i : B F a'
f✝ : B F a' → M F
a✝ : IsPath xs (f✝ i)
h : M.mk { fst := a, snd := f } = M.mk { fst := a', snd := f✝ }
⊢ a = a'

Next tactic:
cases mk_inj h
theorem isPath_cons {xs : Path F} {a a'} {f : F.B a → M F} {i : F.B a'} :
    IsPath (⟨a', i⟩ :: xs) (M.mk ⟨a, f⟩) → a = a' := by
  generalize h : M.mk ⟨a, f⟩ = x
  rintro (_ | ⟨_, _, _, _, rfl, _⟩)
  cases mk_inj h
  

Proof state:
case cons.refl
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a : F.A
f : B F a → M F
i : B F a
a✝ : IsPath xs (f i)
h : M.mk { fst := a, snd := f } = M.mk { fst := a, snd := f }
⊢ a = a

Next tactic:
rfl
theorem isPath_cons' {xs : Path F} {a} {f : F.B a → M F} {i : F.B a} :
    IsPath (⟨a, i⟩ :: xs) (M.mk ⟨a, f⟩) → IsPath xs (f i) := by
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a : F.A
f : B F a → M F
i : B F a
⊢ IsPath ({ fst := a, snd := i } :: xs) (M.mk { fst := a, snd := f }) → IsPath xs (f i)

Next tactic:
generalize h : M.mk ⟨a, f⟩ = x
theorem isPath_cons' {xs : Path F} {a} {f : F.B a → M F} {i : F.B a} :
    IsPath (⟨a, i⟩ :: xs) (M.mk ⟨a, f⟩) → IsPath xs (f i) := by
  generalize h : M.mk ⟨a, f⟩ = x
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a : F.A
f : B F a → M F
i : B F a
x : M F
h : M.mk { fst := a, snd := f } = x
⊢ IsPath ({ fst := a, snd := i } :: xs) x → IsPath xs (f i)

Next tactic:
rintro (_ | ⟨_, _, _, _, rfl, hp⟩)
theorem isPath_cons' {xs : Path F} {a} {f : F.B a → M F} {i : F.B a} :
    IsPath (⟨a, i⟩ :: xs) (M.mk ⟨a, f⟩) → IsPath xs (f i) := by
  generalize h : M.mk ⟨a, f⟩ = x
  rintro (_ | ⟨_, _, _, _, rfl, hp⟩)
  

Proof state:
case cons
F : PFunctor.{u}
X : Type u_1
f✝¹ : X → ↑F X
xs : Path F
a : F.A
f : B F a → M F
i : B F a
f✝ : B F a → M F
hp : IsPath xs (f✝ i)
h : M.mk { fst := a, snd := f } = M.mk { fst := a, snd := f✝ }
⊢ IsPath xs (f i)

Next tactic:
cases mk_inj h
theorem isPath_cons' {xs : Path F} {a} {f : F.B a → M F} {i : F.B a} :
    IsPath (⟨a, i⟩ :: xs) (M.mk ⟨a, f⟩) → IsPath xs (f i) := by
  generalize h : M.mk ⟨a, f⟩ = x
  rintro (_ | ⟨_, _, _, _, rfl, hp⟩)
  cases mk_inj h
  

Proof state:
case cons.refl
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
xs : Path F
a : F.A
f : B F a → M F
i : B F a
hp : IsPath xs (f i)
h : M.mk { fst := a, snd := f } = M.mk { fst := a, snd := f }
⊢ IsPath xs (f i)

Next tactic:
exact hp
/-- follow a path through a value of `M F` and return the subtree
found at the end of the path if it is a valid path for that value and
return a default tree -/
def isubtree [DecidableEq F.A] [Inhabited (M F)] : Path F → M F → M F
  | [], x => x
  | ⟨a, i⟩ :: ps, x =>
    PFunctor.M.casesOn' (r := fun _ => M F) x (fun a' f =>
      if h : a = a' then
        isubtree ps (f <| cast (by 

Proof state:
F : PFunctor.{u}
X : Type u_1
f✝ : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
a : F.A
i : B F a
ps : List (Idx F)
x : M F
a' : F.A
f : B F a' → M F
h : a = a'
⊢ B F a = B F a'

Next tactic:
rw [h]
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  

Proof state:
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps : Path F
x : M F
h : ¬IsPath ps x
⊢ iselect ps x = head default

Next tactic:
induction' ps with ps_hd ps_tail ps_ih generalizing x
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · 

Proof state:
case nil
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
x : M F
h : ¬IsPath [] x
⊢ iselect [] x = head default

Next tactic:
exfalso
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    

Proof state:
case nil.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
x : M F
h : ¬IsPath [] x
⊢ False

Next tactic:
apply h
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    

Proof state:
case nil.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
x : M F
h : ¬IsPath [] x
⊢ IsPath [] x

Next tactic:
constructor
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · 

Proof state:
case cons
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_hd : Idx F
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → iselect ps_tail x = head default
x : M F
h : ¬IsPath (ps_hd :: ps_tail) x
⊢ iselect (ps_hd :: ps_tail) x = head default

Next tactic:
cases' ps_hd with a i
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    

Proof state:
case cons.mk
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → iselect ps_tail x = head default
x : M F
a : F.A
i : B F a
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) x
⊢ iselect ({ fst := a, snd := i } :: ps_tail) x = head default

Next tactic:
induction' x using PFunctor.M.casesOn' with x_a x_f
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    

Proof state:
case cons.mk.f
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → iselect ps_tail x = head default
a : F.A
i : B F a
x_a : F.A
x_f : B F x_a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f })
⊢ iselect ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f }) = head default

Next tactic:
simp only [iselect, isubtree] at ps_ih ⊢
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    

Proof state:
case cons.mk.f
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_a : F.A
x_f : B F x_a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f })
⊢ head
      (M.casesOn' (M.mk { fst := x_a, snd := x_f }) fun a' f =>
        if h : a = a' then isubtree ps_tail (f (cast (_ : B F a = B F a') i)) else default) =
    head default

Next tactic:
by_cases h'' : a = x_a
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    

Proof state:
case pos
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_a : F.A
x_f : B F x_a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f })
h'' : a = x_a
⊢ head
      (M.casesOn' (M.mk { fst := x_a, snd := x_f }) fun a' f =>
        if h : a = a' then isubtree ps_tail (f (cast (_ : B F a = B F a') i)) else default) =
    head default
case neg
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_a : F.A
x_f : B F x_a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f })
h'' : ¬a = x_a
⊢ head
      (M.casesOn' (M.mk { fst := x_a, snd := x_f }) fun a' f =>
        if h : a = a' then isubtree ps_tail (f (cast (_ : B F a = B F a') i)) else default) =
    head default

Next tactic:
subst x_a
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · 

Proof state:
case pos
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
⊢ head
      (M.casesOn' (M.mk { fst := a, snd := x_f }) fun a' f =>
        if h : a = a' then isubtree ps_tail (f (cast (_ : B F a = B F a') i)) else default) =
    head default

Next tactic:
simp only [dif_pos, eq_self_iff_true, casesOn_mk']
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      

Proof state:
case pos
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
⊢ head (isubtree ps_tail (x_f (cast (_ : B F a = B F a) i))) = head default

Next tactic:
rw [ps_ih]
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      

Proof state:
case pos.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
⊢ ¬IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))

Next tactic:
intro h'
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      

Proof state:
case pos.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ False

Next tactic:
apply h
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      

Proof state:
case pos.h
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })

Next tactic:
constructor
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> 

Proof state:
case pos.h.a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ M.mk { fst := a, snd := x_f } = M.mk { fst := a, snd := ?pos.h.f✝ }

Next tactic:
try rfl
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> try 

Proof state:
case pos.h.a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ M.mk { fst := a, snd := x_f } = M.mk { fst := a, snd := ?pos.h.f✝ }

Next tactic:
rfl
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> 

Proof state:
case pos.h.a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ IsPath ps_tail (x_f i)

Next tactic:
try rfl
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> try 

Proof state:
case pos.h.a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ IsPath ps_tail (x_f i)

Next tactic:
rfl
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> try rfl
      

Proof state:
case pos.h.a
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_f : B F a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := a, snd := x_f })
h' : IsPath ps_tail (x_f (cast (_ : B F a = B F a) i))
⊢ IsPath ps_tail (x_f i)

Next tactic:
apply h'
theorem iselect_eq_default [DecidableEq F.A] [Inhabited (M F)] (ps : Path F) (x : M F)
    (h : ¬IsPath ps x) : iselect ps x = head default := by
  induction' ps with ps_hd ps_tail ps_ih generalizing x
  · exfalso
    apply h
    constructor
  · cases' ps_hd with a i
    induction' x using PFunctor.M.casesOn' with x_a x_f
    simp only [iselect, isubtree] at ps_ih ⊢
    by_cases h'' : a = x_a
    subst x_a
    · simp only [dif_pos, eq_self_iff_true, casesOn_mk']
      rw [ps_ih]
      intro h'
      apply h
      constructor <;> try rfl
      apply h'
    · 

Proof state:
case neg
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
inst✝¹ : DecidableEq F.A
inst✝ : Inhabited (M F)
ps_tail : List (Idx F)
ps_ih : ∀ (x : M F), ¬IsPath ps_tail x → head (isubtree ps_tail x) = head default
a : F.A
i : B F a
x_a : F.A
x_f : B F x_a → M F
h : ¬IsPath ({ fst := a, snd := i } :: ps_tail) (M.mk { fst := x_a, snd := x_f })
h'' : ¬a = x_a
⊢ head
      (M.casesOn' (M.mk { fst := x_a, snd := x_f }) fun a' f =>
        if h : a = a' then isubtree ps_tail (f (cast (_ : B F a = B F a') i)) else default) =
    head default

Next tactic:
simp [*]
@[simp]
theorem head_mk (x : F (M F)) : head (M.mk x) = x.1 :=
  Eq.symm <|
    calc
      x.1 = (dest (M.mk x)).1 := by 

Proof state:
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
x : ↑F (M F)
⊢ x.fst = (dest (M.mk x)).fst

Next tactic:
rw [dest_mk]
theorem children_mk {a} (x : F.B a → M F) (i : F.B (head (M.mk ⟨a, x⟩))) :
    children (M.mk ⟨a, x⟩) i = x (cast (by 

Proof state:
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
a : F.A
x : B F a → M F
i : B F (head (M.mk { fst := a, snd := x }))
⊢ B F (head (M.mk { fst := a, snd := x })) = B F a

Next tactic:
rw [head_mk]
theorem children_mk {a} (x : F.B a → M F) (i : F.B (head (M.mk ⟨a, x⟩))) :
    children (M.mk ⟨a, x⟩) i = x (cast (by rw [head_mk]) i) := by 

Proof state:
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
a : F.A
x : B F a → M F
i : B F (head (M.mk { fst := a, snd := x }))
⊢ children (M.mk { fst := a, snd := x }) i = x (cast (_ : B F (head (M.mk { fst := a, snd := x })) = B F a) i)

Next tactic:
apply ext'
theorem children_mk {a} (x : F.B a → M F) (i : F.B (head (M.mk ⟨a, x⟩))) :
    children (M.mk ⟨a, x⟩) i = x (cast (by rw [head_mk]) i) := by apply ext'; 

Proof state:
case H
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
a : F.A
x : B F a → M F
i : B F (head (M.mk { fst := a, snd := x }))
⊢ ∀ (i_1 : ℕ),
    MIntl.approx (children (M.mk { fst := a, snd := x }) i) i_1 =
      MIntl.approx (x (cast (_ : B F (head (M.mk { fst := a, snd := x })) = B F a) i)) i_1

Next tactic:
intro n
theorem children_mk {a} (x : F.B a → M F) (i : F.B (head (M.mk ⟨a, x⟩))) :
    children (M.mk ⟨a, x⟩) i = x (cast (by rw [head_mk]) i) := by apply ext'; intro n; 

Proof state:
case H
F : PFunctor.{u}
X : Type u_1
f : X → ↑F X
a : F.A
x : B F a → M F
i : B F (head (M.mk { fst := a, snd := x }))
n : ℕ
⊢ MIntl.approx (children (M.mk { fst := a, snd := x }) i) n =
    MIntl.approx (x (cast (_ : B F (head (M.mk { fst := a, snd := x })) = B F a) i)) n

Next tactic:
rfl