l3lab/ntp-mathlib huggingface dataset:
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    

Proof state:
case mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α : Type u
x : F₂ (F₁ α)
a : (P F₂).A
f : PFunctor.B (P F₂) a → F₁ α
h : repr x = { fst := a, snd := f }
⊢ abs
      { fst := { fst := a, snd := f }.fst,
        snd := fun x =>
          abs
            { fst := (repr (Sigma.snd { fst := a, snd := f } x)).fst,
              snd := fun y => Sigma.snd (repr (Sigma.snd { fst := a, snd := f } x)) y } } =
    abs { fst := a, snd := f }

Next tactic:
dsimp
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    

Proof state:
case mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α : Type u
x : F₂ (F₁ α)
a : (P F₂).A
f : PFunctor.B (P F₂) a → F₁ α
h : repr x = { fst := a, snd := f }
⊢ abs { fst := a, snd := fun x => abs { fst := (repr (f x)).fst, snd := fun y => Sigma.snd (repr (f x)) y } } =
    abs { fst := a, snd := f }

Next tactic:
congr with x
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    

Proof state:
case mk.e_a.e_snd.h
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α : Type u
x✝ : F₂ (F₁ α)
a : (P F₂).A
f : PFunctor.B (P F₂) a → F₁ α
h : repr x✝ = { fst := a, snd := f }
x : PFunctor.B (P F₂) a
⊢ abs { fst := (repr (f x)).fst, snd := fun y => Sigma.snd (repr (f x)) y } = f x

Next tactic:
cases' h' : repr (f x) with b g
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    

Proof state:
case mk.e_a.e_snd.h.mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α : Type u
x✝ : F₂ (F₁ α)
a : (P F₂).A
f : PFunctor.B (P F₂) a → F₁ α
h : repr x✝ = { fst := a, snd := f }
x : PFunctor.B (P F₂) a
b : (P F₁).A
g : PFunctor.B (P F₁) b → α
h' : repr (f x) = { fst := b, snd := g }
⊢ abs { fst := { fst := b, snd := g }.fst, snd := fun y => Sigma.snd { fst := b, snd := g } y } = f x

Next tactic:
dsimp
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; 

Proof state:
case mk.e_a.e_snd.h.mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α : Type u
x✝ : F₂ (F₁ α)
a : (P F₂).A
f : PFunctor.B (P F₂) a → F₁ α
h : repr x✝ = { fst := a, snd := f }
x : PFunctor.B (P F₂) a
b : (P F₁).A
g : PFunctor.B (P F₁) b → α
h' : repr (f x) = { fst := b, snd := g }
⊢ abs { fst := b, snd := fun y => g y } = f x

Next tactic:
rw [← h', abs_repr]
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    

Proof state:
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
⊢ ∀ (p : ↑(PFunctor.comp (P F₂) (P F₁)) α),
    (fun {α} =>
          id fun p =>
            abs
              { fst := p.fst.fst,
                snd := fun x => abs { fst := Sigma.snd p.fst x, snd := fun y => Sigma.snd p { fst := x, snd := y } } })
        (PFunctor.map (PFunctor.comp (P F₂) (P F₁)) f p) =
      f <$>
        (fun {α} =>
            id fun p =>
              abs
                { fst := p.fst.fst,
                  snd := fun x =>
                    abs { fst := Sigma.snd p.fst x, snd := fun y => Sigma.snd p { fst := x, snd := y } } })
          p

Next tactic:
dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    

Proof state:
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
⊢ ∀
    (p :
      ↑{ A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
            B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
        α),
    abs
        {
          fst :=
            (PFunctor.map
                  { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                    B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                  f p).fst.fst,
          snd := fun x =>
            abs
              {
                fst :=
                  Sigma.snd
                    (PFunctor.map
                        { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                          B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                        f p).fst
                    x,
                snd := fun y =>
                  Sigma.snd
                    (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f p)
                    { fst := x, snd := y } } } =
      f <$>
        abs
          { fst := p.fst.fst,
            snd := fun x => abs { fst := Sigma.snd p.fst x, snd := fun y => Sigma.snd p { fst := x, snd := y } } }

Next tactic:
intro p
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    

Proof state:
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
p :
  ↑{ A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
    α
⊢ abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f p).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f p).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f p)
                  { fst := x, snd := y } } } =
    f <$>
      abs
        { fst := p.fst.fst,
          snd := fun x => abs { fst := Sigma.snd p.fst x, snd := fun y => Sigma.snd p { fst := x, snd := y } } }

Next tactic:
cases' p with a g
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    cases' p with a g; 

Proof state:
case mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
a :
  { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }.A
g :
  PFunctor.B
      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
      a →
    α
⊢ abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f { fst := a, snd := g }).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f { fst := a, snd := g }).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f { fst := a, snd := g })
                  { fst := x, snd := y } } } =
    f <$>
      abs
        { fst := { fst := a, snd := g }.fst.fst,
          snd := fun x =>
            abs
              { fst := Sigma.snd { fst := a, snd := g }.fst x,
                snd := fun y => Sigma.snd { fst := a, snd := g } { fst := x, snd := y } } }

Next tactic:
dsimp
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    cases' p with a g; dsimp
    

Proof state:
case mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
a :
  { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }.A
g :
  PFunctor.B
      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
      a →
    α
⊢ abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f { fst := a, snd := g }).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f { fst := a, snd := g }).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f { fst := a, snd := g })
                  { fst := x, snd := y } } } =
    f <$> abs { fst := a.fst, snd := fun x => abs { fst := Sigma.snd a x, snd := fun y => g { fst := x, snd := y } } }

Next tactic:
cases' a with b h
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    cases' p with a g; dsimp
    cases' a with b h; 

Proof state:
case mk.mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
b : (P F₂).A
h : PFunctor.B (P F₂) b → (P F₁).A
g :
  PFunctor.B
      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
      { fst := b, snd := h } →
    α
⊢ abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f { fst := { fst := b, snd := h }, snd := g }).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f { fst := { fst := b, snd := h }, snd := g }).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f { fst := { fst := b, snd := h }, snd := g })
                  { fst := x, snd := y } } } =
    f <$>
      abs
        { fst := { fst := b, snd := h }.fst,
          snd := fun x => abs { fst := Sigma.snd { fst := b, snd := h } x, snd := fun y => g { fst := x, snd := y } } }

Next tactic:
dsimp
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    cases' p with a g; dsimp
    cases' a with b h; dsimp
    

Proof state:
case mk.mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
b : (P F₂).A
h : PFunctor.B (P F₂) b → (P F₁).A
g :
  PFunctor.B
      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
      { fst := b, snd := h } →
    α
⊢ abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f { fst := { fst := b, snd := h }, snd := g }).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f { fst := { fst := b, snd := h }, snd := g }).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f { fst := { fst := b, snd := h }, snd := g })
                  { fst := x, snd := y } } } =
    f <$> abs { fst := b, snd := fun x => abs { fst := h x, snd := fun y => g { fst := x, snd := y } } }

Next tactic:
symm
/-- composition of qpfs gives another qpf -/
def comp : QPF (Functor.Comp F₂ F₁) where
  P := PFunctor.comp q₂.P q₁.P
  abs {α} := by
    dsimp [Functor.Comp]
    intro p
    exact abs ⟨p.1.1, fun x => abs ⟨p.1.2 x, fun y => p.2 ⟨x, y⟩⟩⟩
  repr {α} := by
    dsimp [Functor.Comp]
    intro y
    refine' ⟨⟨(repr y).1, fun u => (repr ((repr y).2 u)).1⟩, _⟩
    dsimp [PFunctor.comp]
    intro x
    exact (repr ((repr y).2 x.1)).snd x.2
  abs_repr {α} := by
    dsimp [Functor.Comp]
    intro x
    conv =>
      rhs
      rw [← abs_repr x]
    cases' h : repr x with a f
    dsimp
    congr with x
    cases' h' : repr (f x) with b g
    dsimp; rw [← h', abs_repr]
  abs_map {α β} f := by
    dsimp (config := { unfoldPartialApp := true }) [Functor.Comp, PFunctor.comp]
    intro p
    cases' p with a g; dsimp
    cases' a with b h; dsimp
    symm
    

Proof state:
case mk.mk
F₂ : Type u → Type u
inst✝¹ : Functor F₂
q₂ : QPF F₂
F₁ : Type u → Type u
inst✝ : Functor F₁
q₁ : QPF F₁
α β : Type u
f : α → β
b : (P F₂).A
h : PFunctor.B (P F₂) b → (P F₁).A
g :
  PFunctor.B
      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
      { fst := b, snd := h } →
    α
⊢ f <$> abs { fst := b, snd := fun x => abs { fst := h x, snd := fun y => g { fst := x, snd := y } } } =
    abs
      {
        fst :=
          (PFunctor.map
                { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                  B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                f { fst := { fst := b, snd := h }, snd := g }).fst.fst,
        snd := fun x =>
          abs
            {
              fst :=
                Sigma.snd
                  (PFunctor.map
                      { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                        B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                      f { fst := { fst := b, snd := h }, snd := g }).fst
                  x,
              snd := fun y =>
                Sigma.snd
                  (PFunctor.map
                    { A := (a₂ : (P F₂).A) × (PFunctor.B (P F₂) a₂ → (P F₁).A),
                      B := fun a₂a₁ => (u : PFunctor.B (P F₂) a₂a₁.fst) × PFunctor.B (P F₁) (Sigma.snd a₂a₁ u) }
                    f { fst := { fst := b, snd := h }, snd := g })
                  { fst := x, snd := y } } }

Next tactic:
trans