Theorem: IContainer'.M.bisim
Proof state before:
case h₀
I : Type u₀
C : IContainer' I
R : (i : I) → M C i → M C i → Prop
h₀ :
  ∀ (i : I) (x y : M C i),
    R i x y →
      ∃ node k₁ k₂,
        destruct x = { fst := node, snd := k₁ } ∧
          destruct y = { fst := node, snd := k₂ } ∧ ∀ (z : B C ↑node), R (Next C (↑node) z) (k₁ z) (k₂ z)
i✝ : I
x✝ : Container.M (toContainer C)
wfx✝ : WellFormed i✝ x✝
y✝ : Container.M (toContainer C)
wfy✝ : WellFormed i✝ y✝
h₁✝¹ : R i✝ { val := x✝, property := wfx✝ } { val := y✝, property := wfy✝ }
x y : Container.M (toContainer C)
i : I
wfx : WellFormed i x
wfy : WellFormed i y
r : R i { val := x, property := wfx } { val := y, property := wfy }
node : C.A
h₄ : i = Idx C node
k₁ k₂ : (y : B C ↑{ val := node, property := h₄ }) → M C (Next C (↑{ val := node, property := h₄ }) y)
h₁✝ : destruct { val := x, property := wfx } = { fst := { val := node, property := h₄ }, snd := k₁ }
h₂ : destruct { val := y, property := wfy } = { fst := { val := node, property := h₄ }, snd := k₂ }
h₃ : ∀ (z : B C ↑{ val := node, property := h₄ }), R (Next C (↑{ val := node, property := h₄ }) z) (k₁ z) (k₂ z)
h₁ :
  Container.M.destruct x =
    { fst := ↑{ fst := { val := node, property := h₄ }, snd := k₁ }.fst,
      snd := fun x => ↑(Sigma.snd { fst := { val := node, property := h₄ }, snd := k₁ } x) }
⊢ ∃ node k₁ k₂,
    Container.M.destruct x = { fst := node, snd := k₁ } ∧
      Container.M.destruct y = { fst := node, snd := k₂ } ∧
        ∀ (i : Container.B (toContainer C) node),
          ∃ i_1 wfx wfy, R i_1 { val := k₁ i, property := wfx } { val := k₂ i, property := wfy }
Tactic:
have h₂ := lift_destruct_eq _ _ _ _ h₂
Proof state after:
case h₀
I : Type u₀
C : IContainer' I
R : (i : I) → M C i → M C i → Prop
h₀ :
  ∀ (i : I) (x y : M C i),
    R i x y →
      ∃ node k₁ k₂,
        destruct x = { fst := node, snd := k₁ } ∧
          destruct y = { fst := node, snd := k₂ } ∧ ∀ (z : B C ↑node), R (Next C (↑node) z) (k₁ z) (k₂ z)
i✝ : I
x✝ : Container.M (toContainer C)
wfx✝ : WellFormed i✝ x✝
y✝ : Container.M (toContainer C)
wfy✝ : WellFormed i✝ y✝
h₁✝¹ : R i✝ { val := x✝, property := wfx✝ } { val := y✝, property := wfy✝ }
x y : Container.M (toContainer C)
i : I
wfx : WellFormed i x
wfy : WellFormed i y
r : R i { val := x, property := wfx } { val := y, property := wfy }
node : C.A
h₄ : i = Idx C node
k₁ k₂ : (y : B C ↑{ val := node, property := h₄ }) → M C (Next C (↑{ val := node, property := h₄ }) y)
h₁✝ : destruct { val := x, property := wfx } = { fst := { val := node, property := h₄ }, snd := k₁ }
h₂✝ : destruct { val := y, property := wfy } = { fst := { val := node, property := h₄ }, snd := k₂ }
h₃ : ∀ (z : B C ↑{ val := node, property := h₄ }), R (Next C (↑{ val := node, property := h₄ }) z) (k₁ z) (k₂ z)
h₁ :
  Container.M.destruct x =
    { fst := ↑{ fst := { val := node, property := h₄ }, snd := k₁ }.fst,
      snd := fun x => ↑(Sigma.snd { fst := { val := node, property := h₄ }, snd := k₁ } x) }
h₂ :
  Container.M.destruct y =
    { fst := ↑{ fst := { val := node, property := h₄ }, snd := k₂ }.fst,
      snd := fun x => ↑(Sigma.snd { fst := { val := node, property := h₄ }, snd := k₂ } x) }
⊢ ∃ node k₁ k₂,
    Container.M.destruct x = { fst := node, snd := k₁ } ∧
      Container.M.destruct y = { fst := node, snd := k₂ } ∧
        ∀ (i : Container.B (toContainer C) node),
          ∃ i_1 wfx wfy, R i_1 { val := k₁ i, property := wfx } { val := k₂ i, property := wfy }