Theorem: PFunctor.M.corec_unique
File: Mathlib/Data/PFunctor/Univariate/M.lean

tactic: ext x
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
⊢ f = M.corec g

tactic: apply bisim' (fun _ => True) _ _ _ _ trivial
state_before: case h
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
⊢ f x = M.corec g x

tactic: clear x
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
⊢ ∀ (x : α),
    (fun x => True) x →
      ∃ a f_1 f',
        dest (f x) = { fst := a, snd := f_1 } ∧
          dest (M.corec g x) = { fst := a, snd := f' } ∧
            ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: intro x _
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
⊢ ∀ (x : α),
    (fun x => True) x →
      ∃ a f_1 f',
        dest (f x) = { fst := a, snd := f_1 } ∧
          dest (M.corec g x) = { fst := a, snd := f' } ∧
            ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: cases' gxeq : g x with a f'
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
⊢ ∃ a f_1 f',
    dest (f x) = { fst := a, snd := f_1 } ∧
      dest (M.corec g x) = { fst := a, snd := f' } ∧
        ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: have h₀ : M.dest (f x) = ⟨a, f ∘ f'⟩ := by rw [hyp, gxeq, PFunctor.map_eq]
state_before: case mk
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
⊢ ∃ a f_1 f',
    dest (f x) = { fst := a, snd := f_1 } ∧
      dest (M.corec g x) = { fst := a, snd := f' } ∧
        ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: have h₁ : M.dest (M.corec g x) = ⟨a, M.corec g ∘ f'⟩ := by rw [dest_corec, gxeq, PFunctor.map_eq]
state_before: case mk
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
h₀ : dest (f x) = { fst := a, snd := f ∘ f' }
⊢ ∃ a f_1 f',
    dest (f x) = { fst := a, snd := f_1 } ∧
      dest (M.corec g x) = { fst := a, snd := f' } ∧
        ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: refine' ⟨_, _, _, h₀, h₁, _⟩
state_before: case mk
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
h₀ : dest (f x) = { fst := a, snd := f ∘ f' }
h₁ : dest (M.corec g x) = { fst := a, snd := M.corec g ∘ f' }
⊢ ∃ a f_1 f',
    dest (f x) = { fst := a, snd := f_1 } ∧
      dest (M.corec g x) = { fst := a, snd := f' } ∧
        ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ f_1 i = f x' ∧ f' i = M.corec g x'

tactic: intro i
state_before: case mk
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
h₀ : dest (f x) = { fst := a, snd := f ∘ f' }
h₁ : dest (M.corec g x) = { fst := a, snd := M.corec g ∘ f' }
⊢ ∀ (i : B P a), ∃ x', (fun x => True) x' ∧ (f ∘ f') i = f x' ∧ (M.corec g ∘ f') i = M.corec g x'

tactic: exact ⟨f' i, trivial, rfl, rfl⟩
state_before: case mk
F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
h₀ : dest (f x) = { fst := a, snd := f ∘ f' }
h₁ : dest (M.corec g x) = { fst := a, snd := M.corec g ∘ f' }
i : B P a
⊢ ∃ x', (fun x => True) x' ∧ (f ∘ f') i = f x' ∧ (M.corec g ∘ f') i = M.corec g x'

tactic: rw [hyp, gxeq, PFunctor.map_eq]
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
⊢ dest (f x) = { fst := a, snd := f ∘ f' }

tactic: rw [dest_corec, gxeq, PFunctor.map_eq]
state_before: F : PFunctor
X : Type ?u.75905
f✝ : X → Obj F X
P : PFunctor
α : Type u
g : α → Obj P α
f : α → M P
hyp : ∀ (x : α), dest (f x) = f <$> g x
x : α
a✝ : True
a : P.A
f' : B P a → α
gxeq : g x = { fst := a, snd := f' }
h₀ : dest (f x) = { fst := a, snd := f ∘ f' }
⊢ dest (M.corec g x) = { fst := a, snd := M.corec g ∘ f' }