Theorem: IContainer.M.bisim (CoInd/MIdx.lean)

State before:
case refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy' : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
h₂ : destruct { val := y, property := wfy } = { fst := ny, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst ny), R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (k₂ z)
a : B C (Container.M.destruct y).fst.fst ny
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a) ((fun x => ↑(k₂ x)) a)
Tactic:
have h₂ := Sigma.snd_equals _ _ _ h₂
State after:
case refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy' : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
h₂✝ : destruct { val := y, property := wfy } = { fst := ny, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst ny), R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (k₂ z)
a : B C (Container.M.destruct y).fst.fst ny
h₂ : (destruct { val := y, property := wfy }).snd = k₂
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a) ((fun x => ↑(k₂ x)) a)

State before:
case refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy' : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
h₂✝ : destruct { val := y, property := wfy } = { fst := ny, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst ny), R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (k₂ z)
a : B C (Container.M.destruct y).fst.fst ny
h₂ : (destruct { val := y, property := wfy }).snd = k₂
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a) ((fun x => ↑(k₂ x)) a)
Tactic:
have wfy' := wfy' a
State after:
case refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy'✝ : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
h₂✝ : destruct { val := y, property := wfy } = { fst := ny, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst ny), R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (k₂ z)
a : B C (Container.M.destruct y).fst.fst ny
h₂ : (destruct { val := y, property := wfy }).snd = k₂
wfy' : WellFormed (N C iy ny a) (ky a)
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a) ((fun x => ↑(k₂ x)) a)

State before:
case refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy'✝ : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
h₂✝ : destruct { val := y, property := wfy } = { fst := ny, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst ny), R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (k₂ z)
a : B C (Container.M.destruct y).fst.fst ny
h₂ : (destruct { val := y, property := wfy }).snd = k₂
wfy' : WellFormed (N C iy ny a) (ky a)
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a) ((fun x => ↑(k₂ x)) a)
Tactic:
cases h₂
State after:
case refl.refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy'✝ : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
a : B C (Container.M.destruct y).fst.fst ny
wfy' : WellFormed (N C iy ny a) (ky a)
h₂ : destruct { val := y, property := wfy } = { fst := ny, snd := (destruct { val := y, property := wfy }).snd }
h₃ :
  ∀ (z : B C (Container.M.destruct y).fst.fst ny),
    R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (Sigma.snd (destruct { val := y, property := wfy }) z)
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a)
    ((fun x => ↑(Sigma.snd (destruct { val := y, property := wfy }) x)) a)

State before:
case refl.refl.refl
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy'✝ : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
k₁ : (y_1 : B C (Container.M.destruct y).fst.fst ny) → M C (N C (Container.M.destruct y).fst.fst ny y_1)
h₁ : destruct { val := x, property := wfx } = { fst := ny, snd := k₁ }
a : B C (Container.M.destruct y).fst.fst ny
wfy' : WellFormed (N C iy ny a) (ky a)
h₂ : destruct { val := y, property := wfy } = { fst := ny, snd := (destruct { val := y, property := wfy }).snd }
h₃ :
  ∀ (z : B C (Container.M.destruct y).fst.fst ny),
    R (N C (Container.M.destruct y).fst.fst ny z) (k₁ z) (Sigma.snd (destruct { val := y, property := wfy }) z)
⊢ WellFormed (N C (Container.M.destruct y).fst.fst ny a)
    ((fun x => ↑(Sigma.snd (destruct { val := y, property := wfy }) x)) a)
Tactic:
exact wfy'
State after:
no goals

State before:
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 i node), R (N C i 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)
ix : I := (Container.M.destruct x).fst.fst
nx : A C (Container.M.destruct x).fst.fst := (Container.M.destruct x).fst.snd
kx : Container.B (toContainer C) (Container.M.destruct x).fst → Container.M (toContainer C) :=
  (Container.M.destruct x).snd
iy : I := (Container.M.destruct y).fst.fst
ny : A C (Container.M.destruct y).fst.fst := (Container.M.destruct y).fst.snd
ky : Container.B (toContainer C) (Container.M.destruct y).fst → Container.M (toContainer C) :=
  (Container.M.destruct y).snd
wfx' : ∀ (a : B C ix nx), WellFormed (N C ix nx a) (kx a)
wfy' : ∀ (a : B C iy ny), WellFormed (N C iy ny a) (ky a)
wfx : WellFormed (Container.M.destruct y).fst.fst x
wfy : WellFormed (Container.M.destruct y).fst.fst y
r : R (Container.M.destruct y).fst.fst { val := x, property := wfx } { val := y, property := wfy }
node : A C (Container.M.destruct y).fst.fst
k₁ k₂ : (y_1 : B C (Container.M.destruct y).fst.fst node) → M C (N C (Container.M.destruct y).fst.fst node y_1)
h₁ : destruct { val := x, property := wfx } = { fst := node, snd := k₁ }
h₂ : destruct { val := y, property := wfy } = { fst := node, snd := k₂ }
h₃ : ∀ (z : B C (Container.M.destruct y).fst.fst node), R (N C (Container.M.destruct y).fst.fst node z) (k₁ z) (k₂ z)
hix : (Container.M.destruct y).fst.fst = (Container.M.destruct x).fst.fst
a : B C (Container.M.destruct y).fst.fst node
⊢ ny = node
Tactic:
apply congrArg Sigma.fst h₂
State after:
no goals