[GOAL]
α : Type u
β : Type v
γ : Type w
R✝ : α → β → Prop
s : WSeq α
t : WSeq β
R : WSeq α → WSeq β → Prop
h1 : R s t
h2 : ∀ {s : WSeq α} {t : WSeq β}, R s t → Computation.LiftRel (LiftRelO R✝ R) (destruct s) (destruct t)
⊢ Computation.LiftRel (LiftRelO R✝ (LiftRel R✝)) (destruct s) (destruct t)
[PROOFSTEP]
refine' Computation.LiftRel.imp _ _ _ (h2 h1)
[GOAL]
α : Type u
β : Type v
γ : Type w
R✝ : α → β → Prop
s : WSeq α
t : WSeq β
R : WSeq α → WSeq β → Prop
h1 : R s t
h2 : ∀ {s : WSeq α} {t : WSeq β}, R s t → Computation.LiftRel (LiftRelO R✝ R) (destruct s) (destruct t)
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)}, LiftRelO R✝ R a b → LiftRelO R✝ (LiftRel R✝) a b
[PROOFSTEP]
apply LiftRelO.imp_right
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R✝ : α → β → Prop
s : WSeq α
t : WSeq β
R : WSeq α → WSeq β → Prop
h1 : R s t
h2 : ∀ {s : WSeq α} {t : WSeq β}, R s t → Computation.LiftRel (LiftRelO R✝ R) (destruct s) (destruct t)
⊢ ∀ (s : WSeq α) (t : WSeq β), R s t → LiftRel R✝ s t
[PROOFSTEP]
exact fun s' t' h' => ⟨R, h', @h2⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
⊢ Computation.LiftRel
    (LiftRelO R fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t))
    (destruct s) (destruct t)
[PROOFSTEP]
have h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t) :=
  by
  cases' h with h h
  exact liftRel_destruct h
  assumption
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
cases' h with h h
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
case inr
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
exact liftRel_destruct h
[GOAL]
case inr
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
assumption
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
⊢ Computation.LiftRel
    (LiftRelO R fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t))
    (destruct s) (destruct t)
[PROOFSTEP]
apply Computation.LiftRel.imp _ _ _ h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      LiftRelO R (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) a b
[PROOFSTEP]
intro a b
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ LiftRelO R (LiftRel R) a b →
    LiftRelO R (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) a b
[PROOFSTEP]
apply LiftRelO.imp_right
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s t
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ ∀ (s : WSeq α) (t : WSeq β),
    LiftRel R s t → LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
intro s t
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝¹ : WSeq α
t✝¹ : WSeq β
h✝¹ : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝¹) (destruct t✝¹)
s✝ : WSeq α
t✝ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)) s✝ t✝
h : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
⊢ LiftRel R s t → LiftRel R s t ∨ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
apply Or.inl
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s : WSeq α
⊢ LiftRel R s s
[PROOFSTEP]
refine' ⟨(· = ·), rfl, fun {s t} (h : s = t) => _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
⊢ Computation.LiftRel (LiftRelO R fun x x_1 => x = x_1) (destruct s) (destruct t)
[PROOFSTEP]
rw [← h]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
⊢ Computation.LiftRel (LiftRelO R fun x x_1 => x = x_1) (destruct s) (destruct s)
[PROOFSTEP]
apply Computation.LiftRel.refl
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
⊢ Reflexive (LiftRelO R fun x x_1 => x = x_1)
[PROOFSTEP]
intro a
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
a : Option (α × WSeq α)
⊢ LiftRelO R (fun x x_1 => x = x_1) a a
[PROOFSTEP]
cases' a with a
[GOAL]
case H.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
⊢ LiftRelO R (fun x x_1 => x = x_1) none none
[PROOFSTEP]
simp
[GOAL]
case H.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
a : α × WSeq α
⊢ LiftRelO R (fun x x_1 => x = x_1) (some a) (some a)
[PROOFSTEP]
cases a
[GOAL]
case H.some.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
fst✝ : α
snd✝ : WSeq α
⊢ LiftRelO R (fun x x_1 => x = x_1) (some (fst✝, snd✝)) (some (fst✝, snd✝))
[PROOFSTEP]
simp only [LiftRelO, and_true]
[GOAL]
case H.some.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Reflexive R
s✝ s t : WSeq α
h : s = t
fst✝ : α
snd✝ : WSeq α
⊢ R fst✝ fst✝
[PROOFSTEP]
apply H
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
⊢ Function.swap (LiftRelO R C) = LiftRelO (Function.swap R) (Function.swap C)
[PROOFSTEP]
funext x y
[GOAL]
case h.h
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
x : Option (β × WSeq β)
y : Option (α × WSeq α)
⊢ Function.swap (LiftRelO R C) x y = LiftRelO (Function.swap R) (Function.swap C) x y
[PROOFSTEP]
cases' x with x <;> [skip; cases x]
[GOAL]
case h.h
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
x : Option (β × WSeq β)
y : Option (α × WSeq α)
⊢ Function.swap (LiftRelO R C) x y = LiftRelO (Function.swap R) (Function.swap C) x y
[PROOFSTEP]
cases' x with x
[GOAL]
case h.h.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
⊢ Function.swap (LiftRelO R C) none y = LiftRelO (Function.swap R) (Function.swap C) none y
[PROOFSTEP]
skip
[GOAL]
case h.h.some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
x : β × WSeq β
⊢ Function.swap (LiftRelO R C) (some x) y = LiftRelO (Function.swap R) (Function.swap C) (some x) y
[PROOFSTEP]
cases x
[GOAL]
case h.h.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
⊢ Function.swap (LiftRelO R C) none y = LiftRelO (Function.swap R) (Function.swap C) none y
[PROOFSTEP]
cases' y with y <;> [skip; cases y]
[GOAL]
case h.h.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
⊢ Function.swap (LiftRelO R C) none y = LiftRelO (Function.swap R) (Function.swap C) none y
[PROOFSTEP]
cases' y with y
[GOAL]
case h.h.none.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
⊢ Function.swap (LiftRelO R C) none none = LiftRelO (Function.swap R) (Function.swap C) none none
[PROOFSTEP]
skip
[GOAL]
case h.h.none.some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : α × WSeq α
⊢ Function.swap (LiftRelO R C) none (some y) = LiftRelO (Function.swap R) (Function.swap C) none (some y)
[PROOFSTEP]
cases y
[GOAL]
case h.h.none.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
⊢ Function.swap (LiftRelO R C) none none = LiftRelO (Function.swap R) (Function.swap C) none none
[PROOFSTEP]
rfl
[GOAL]
case h.h.none.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
fst✝ : α
snd✝ : WSeq α
⊢ Function.swap (LiftRelO R C) none (some (fst✝, snd✝)) =
    LiftRelO (Function.swap R) (Function.swap C) none (some (fst✝, snd✝))
[PROOFSTEP]
rfl
[GOAL]
case h.h.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
fst✝ : β
snd✝ : WSeq β
⊢ Function.swap (LiftRelO R C) (some (fst✝, snd✝)) y =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝, snd✝)) y
[PROOFSTEP]
cases' y with y <;> [skip; cases y]
[GOAL]
case h.h.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
y : Option (α × WSeq α)
fst✝ : β
snd✝ : WSeq β
⊢ Function.swap (LiftRelO R C) (some (fst✝, snd✝)) y =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝, snd✝)) y
[PROOFSTEP]
cases' y with y
[GOAL]
case h.h.some.mk.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
fst✝ : β
snd✝ : WSeq β
⊢ Function.swap (LiftRelO R C) (some (fst✝, snd✝)) none =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝, snd✝)) none
[PROOFSTEP]
skip
[GOAL]
case h.h.some.mk.some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
fst✝ : β
snd✝ : WSeq β
y : α × WSeq α
⊢ Function.swap (LiftRelO R C) (some (fst✝, snd✝)) (some y) =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝, snd✝)) (some y)
[PROOFSTEP]
cases y
[GOAL]
case h.h.some.mk.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
fst✝ : β
snd✝ : WSeq β
⊢ Function.swap (LiftRelO R C) (some (fst✝, snd✝)) none =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝, snd✝)) none
[PROOFSTEP]
rfl
[GOAL]
case h.h.some.mk.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
C : WSeq α → WSeq β → Prop
fst✝¹ : β
snd✝¹ : WSeq β
fst✝ : α
snd✝ : WSeq α
⊢ Function.swap (LiftRelO R C) (some (fst✝¹, snd✝¹)) (some (fst✝, snd✝)) =
    LiftRelO (Function.swap R) (Function.swap C) (some (fst✝¹, snd✝¹)) (some (fst✝, snd✝))
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 : WSeq α
s2 : WSeq β
h : LiftRel R s1 s2
⊢ LiftRel (swap R) s2 s1
[PROOFSTEP]
refine' ⟨swap (LiftRel R), h, fun {s t} (h : LiftRel R t s) => _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 : WSeq α
s2 : WSeq β
h✝ : LiftRel R s1 s2
s : WSeq β
t : WSeq α
h : LiftRel R t s
⊢ Computation.LiftRel (LiftRelO (swap R) (swap (LiftRel R))) (destruct s) (destruct t)
[PROOFSTEP]
rw [← LiftRelO.swap, Computation.LiftRel.swap]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 : WSeq α
s2 : WSeq β
h✝ : LiftRel R s1 s2
s : WSeq β
t : WSeq α
h : LiftRel R t s
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct s)
[PROOFSTEP]
apply liftRel_destruct h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Symmetric R
s1 s2 : WSeq α
h : Function.swap (LiftRel R) s2 s1
⊢ LiftRel R s2 s1
[PROOFSTEP]
rwa [LiftRel.swap, H.swap_eq] at h 
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s t u : WSeq α
h1 : LiftRel R s t
h2 : LiftRel R t u
⊢ LiftRel R s u
[PROOFSTEP]
refine' ⟨fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u, ⟨t, h1, h2⟩, fun {s u} h => _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t u✝ : WSeq α
h1 : LiftRel R s✝ t
h2 : LiftRel R t u✝
s u : WSeq α
h : (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) s u
⊢ Computation.LiftRel (LiftRelO R fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (destruct s) (destruct u)
[PROOFSTEP]
rcases h with ⟨t, h1, h2⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u✝
s u t : WSeq α
h1 : LiftRel R s t
h2 : LiftRel R t u
⊢ Computation.LiftRel (LiftRelO R fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (destruct s) (destruct u)
[PROOFSTEP]
have h1 := liftRel_destruct h1
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2 : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
⊢ Computation.LiftRel (LiftRelO R fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (destruct s) (destruct u)
[PROOFSTEP]
have h2 := liftRel_destruct h2
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
⊢ Computation.LiftRel (LiftRelO R fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (destruct s) (destruct u)
[PROOFSTEP]
refine'
  Computation.liftRel_def.2
    ⟨(Computation.terminates_of_LiftRel h1).trans (Computation.terminates_of_LiftRel h2), fun {a c} ha hc => _⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
a c : Option (α × WSeq α)
ha : a ∈ destruct s
hc : c ∈ destruct u
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) a c
[PROOFSTEP]
rcases h1.left ha with ⟨b, hb, t1⟩
[GOAL]
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
a c : Option (α × WSeq α)
ha : a ∈ destruct s
hc : c ∈ destruct u
b : Option (α × WSeq α)
hb : b ∈ destruct t
t1 : LiftRelO R (LiftRel R) a b
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) a c
[PROOFSTEP]
have t2 := Computation.rel_of_LiftRel h2 hb hc
[GOAL]
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
a c : Option (α × WSeq α)
ha : a ∈ destruct s
hc : c ∈ destruct u
b : Option (α × WSeq α)
hb : b ∈ destruct t
t1 : LiftRelO R (LiftRel R) a b
t2 : LiftRelO R (LiftRel R) b c
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) a c
[PROOFSTEP]
cases' a with a
[GOAL]
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
c : Option (α × WSeq α)
hc : c ∈ destruct u
b : Option (α × WSeq α)
hb : b ∈ destruct t
t2 : LiftRelO R (LiftRel R) b c
ha : none ∈ destruct s
t1 : LiftRelO R (LiftRel R) none b
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) none c
[PROOFSTEP]
cases' c with c
[GOAL]
case intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
c : Option (α × WSeq α)
hc : c ∈ destruct u
b : Option (α × WSeq α)
hb : b ∈ destruct t
t2 : LiftRelO R (LiftRel R) b c
a : α × WSeq α
ha : some a ∈ destruct s
t1 : LiftRelO R (LiftRel R) (some a) b
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some a) c
[PROOFSTEP]
cases' c with c
[GOAL]
case intro.intro.intro.intro.none.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
ha : none ∈ destruct s
t1 : LiftRelO R (LiftRel R) none b
hc : none ∈ destruct u
t2 : LiftRelO R (LiftRel R) b none
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) none none
[PROOFSTEP]
trivial
[GOAL]
case intro.intro.intro.intro.none.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
ha : none ∈ destruct s
t1 : LiftRelO R (LiftRel R) none b
c : α × WSeq α
hc : some c ∈ destruct u
t2 : LiftRelO R (LiftRel R) b (some c)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) none (some c)
[PROOFSTEP]
cases b
[GOAL]
case intro.intro.intro.intro.none.some.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
ha : none ∈ destruct s
c : α × WSeq α
hc : some c ∈ destruct u
hb : none ∈ destruct t
t1 : LiftRelO R (LiftRel R) none none
t2 : LiftRelO R (LiftRel R) none (some c)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) none (some c)
[PROOFSTEP]
cases t2
[GOAL]
case intro.intro.intro.intro.none.some.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
ha : none ∈ destruct s
c : α × WSeq α
hc : some c ∈ destruct u
val✝ : α × WSeq α
hb : some val✝ ∈ destruct t
t1 : LiftRelO R (LiftRel R) none (some val✝)
t2 : LiftRelO R (LiftRel R) (some val✝) (some c)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) none (some c)
[PROOFSTEP]
cases t1
[GOAL]
case intro.intro.intro.intro.some.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
a : α × WSeq α
ha : some a ∈ destruct s
t1 : LiftRelO R (LiftRel R) (some a) b
hc : none ∈ destruct u
t2 : LiftRelO R (LiftRel R) b none
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some a) none
[PROOFSTEP]
cases a
[GOAL]
case intro.intro.intro.intro.some.none.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
hc : none ∈ destruct u
t2 : LiftRelO R (LiftRel R) b none
fst✝ : α
snd✝ : WSeq α
ha : some (fst✝, snd✝) ∈ destruct s
t1 : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) b
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (fst✝, snd✝)) none
[PROOFSTEP]
cases' b with b
[GOAL]
case intro.intro.intro.intro.some.none.mk.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
hc : none ∈ destruct u
fst✝ : α
snd✝ : WSeq α
ha : some (fst✝, snd✝) ∈ destruct s
hb : none ∈ destruct t
t2 : LiftRelO R (LiftRel R) none none
t1 : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) none
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (fst✝, snd✝)) none
[PROOFSTEP]
cases t1
[GOAL]
case intro.intro.intro.intro.some.none.mk.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
hc : none ∈ destruct u
fst✝ : α
snd✝ : WSeq α
ha : some (fst✝, snd✝) ∈ destruct s
b : α × WSeq α
hb : some b ∈ destruct t
t2 : LiftRelO R (LiftRel R) (some b) none
t1 : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) (some b)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (fst✝, snd✝)) none
[PROOFSTEP]
cases b
[GOAL]
case intro.intro.intro.intro.some.none.mk.some.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
hc : none ∈ destruct u
fst✝¹ : α
snd✝¹ : WSeq α
ha : some (fst✝¹, snd✝¹) ∈ destruct s
fst✝ : α
snd✝ : WSeq α
hb : some (fst✝, snd✝) ∈ destruct t
t2 : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) none
t1 : LiftRelO R (LiftRel R) (some (fst✝¹, snd✝¹)) (some (fst✝, snd✝))
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (fst✝¹, snd✝¹)) none
[PROOFSTEP]
cases t2
[GOAL]
case intro.intro.intro.intro.some.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝ t✝
h2✝¹ : LiftRel R t✝ u✝
s u t : WSeq α
h1✝ : LiftRel R s t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
a : α × WSeq α
ha : some a ∈ destruct s
t1 : LiftRelO R (LiftRel R) (some a) b
c : α × WSeq α
hc : some c ∈ destruct u
t2 : LiftRelO R (LiftRel R) b (some c)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some a) (some c)
[PROOFSTEP]
cases' a with a s
[GOAL]
case intro.intro.intro.intro.some.some.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝
h2✝¹ : LiftRel R t✝ u✝
s✝ u t : WSeq α
h1✝ : LiftRel R s✝ t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
b : Option (α × WSeq α)
hb : b ∈ destruct t
c : α × WSeq α
hc : some c ∈ destruct u
t2 : LiftRelO R (LiftRel R) b (some c)
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
t1 : LiftRelO R (LiftRel R) (some (a, s)) b
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some c)
[PROOFSTEP]
cases' b with b
[GOAL]
case intro.intro.intro.intro.some.some.mk.none
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝
h2✝¹ : LiftRel R t✝ u✝
s✝ u t : WSeq α
h1✝ : LiftRel R s✝ t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
c : α × WSeq α
hc : some c ∈ destruct u
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
hb : none ∈ destruct t
t2 : LiftRelO R (LiftRel R) none (some c)
t1 : LiftRelO R (LiftRel R) (some (a, s)) none
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some c)
[PROOFSTEP]
cases t1
[GOAL]
case intro.intro.intro.intro.some.some.mk.some
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝ u✝ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝
h2✝¹ : LiftRel R t✝ u✝
s✝ u t : WSeq α
h1✝ : LiftRel R s✝ t
h2✝ : LiftRel R t u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t) (destruct u)
c : α × WSeq α
hc : some c ∈ destruct u
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
b : α × WSeq α
hb : some b ∈ destruct t
t2 : LiftRelO R (LiftRel R) (some b) (some c)
t1 : LiftRelO R (LiftRel R) (some (a, s)) (some b)
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some c)
[PROOFSTEP]
cases' b with b t
[GOAL]
case intro.intro.intro.intro.some.some.mk.some.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝¹ u✝ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝¹
h2✝¹ : LiftRel R t✝¹ u✝
s✝ u t✝ : WSeq α
h1✝ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t✝) (destruct u)
c : α × WSeq α
hc : some c ∈ destruct u
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
b : α
t : WSeq α
hb : some (b, t) ∈ destruct t✝
t2 : LiftRelO R (LiftRel R) (some (b, t)) (some c)
t1 : LiftRelO R (LiftRel R) (some (a, s)) (some (b, t))
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some c)
[PROOFSTEP]
cases' c with c u
[GOAL]
case intro.intro.intro.intro.some.some.mk.some.mk.mk
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝¹ u✝¹ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝¹
h2✝¹ : LiftRel R t✝¹ u✝¹
s✝ u✝ t✝ : WSeq α
h1✝ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u✝
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t✝) (destruct u✝)
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
b : α
t : WSeq α
hb : some (b, t) ∈ destruct t✝
t1 : LiftRelO R (LiftRel R) (some (a, s)) (some (b, t))
c : α
u : WSeq α
hc : some (c, u) ∈ destruct u✝
t2 : LiftRelO R (LiftRel R) (some (b, t)) (some (c, u))
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some (c, u))
[PROOFSTEP]
cases' t1 with ab st
[GOAL]
case intro.intro.intro.intro.some.some.mk.some.mk.mk.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝¹ u✝¹ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝¹
h2✝¹ : LiftRel R t✝¹ u✝¹
s✝ u✝ t✝ : WSeq α
h1✝ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u✝
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t✝) (destruct u✝)
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
b : α
t : WSeq α
hb : some (b, t) ∈ destruct t✝
c : α
u : WSeq α
hc : some (c, u) ∈ destruct u✝
t2 : LiftRelO R (LiftRel R) (some (b, t)) (some (c, u))
ab : R a b
st : LiftRel R s t
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some (c, u))
[PROOFSTEP]
cases' t2 with bc tu
[GOAL]
case intro.intro.intro.intro.some.some.mk.some.mk.mk.intro.intro
α : Type u
β : Type v
γ : Type w
R : α → α → Prop
H : Transitive R
s✝¹ t✝¹ u✝¹ : WSeq α
h1✝¹ : LiftRel R s✝¹ t✝¹
h2✝¹ : LiftRel R t✝¹ u✝¹
s✝ u✝ t✝ : WSeq α
h1✝ : LiftRel R s✝ t✝
h2✝ : LiftRel R t✝ u✝
h1 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s✝) (destruct t✝)
h2 : Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct t✝) (destruct u✝)
a : α
s : WSeq α
ha : some (a, s) ∈ destruct s✝
b : α
t : WSeq α
hb : some (b, t) ∈ destruct t✝
c : α
u : WSeq α
hc : some (c, u) ∈ destruct u✝
ab : R a b
st : LiftRel R s t
bc : R b c
tu : LiftRel R t u
⊢ LiftRelO R (fun s u => ∃ t, LiftRel R s t ∧ LiftRel R t u) (some (a, s)) (some (c, u))
[PROOFSTEP]
exact ⟨H ab bc, t, st, tu⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ Computation.destruct (destruct (cons a s)) = Sum.inl (some (a, s))
[PROOFSTEP]
simp [destruct, cons, Computation.rmap]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ Computation.destruct (destruct (think s)) = Sum.inr (destruct s)
[PROOFSTEP]
simp [destruct, think, Computation.rmap]
[GOAL]
α : Type u
β : Type v
γ : Type w
⊢ head nil = Computation.pure none
[PROOFSTEP]
simp [head]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ head (cons a s) = Computation.pure (some a)
[PROOFSTEP]
simp [head]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ head (think s) = Computation.think (head s)
[PROOFSTEP]
simp [head]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ flatten (Computation.pure s) = s
[PROOFSTEP]
refine' Seq.eq_of_bisim (fun s1 s2 => flatten (Computation.pure s2) = s1) _ rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ Seq.IsBisimulation fun s1 s2 => flatten (Computation.pure s2) = s1
[PROOFSTEP]
intro s' s h
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
⊢ Seq.BisimO (fun s1 s2 => flatten (Computation.pure s2) = s1) (Seq.destruct s') (Seq.destruct s)
[PROOFSTEP]
rw [← h]
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
⊢ Seq.BisimO (fun s1 s2 => flatten (Computation.pure s2) = s1) (Seq.destruct (flatten (Computation.pure s)))
    (Seq.destruct s)
[PROOFSTEP]
simp [flatten]
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
⊢ match
    match
      match Seq.destruct s with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    Seq.destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]
cases Seq.destruct s with
| none => simp
| some val =>
  cases' val with o s'
  simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
x✝ : Option (Seq1 (Option α))
⊢ match
    match
      match x✝ with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    x✝ with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]
cases Seq.destruct s with
| none => simp
| some val =>
  cases' val with o s'
  simp
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
⊢ match
    match
      match none with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    none with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]

| none => simp
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
⊢ match
    match
      match none with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    none with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
val : Seq1 (Option α)
⊢ match
    match
      match some val with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    some val with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]

| some val =>
  cases' val with o s'
  simp
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s' s : Seq (Option α)
h : flatten (Computation.pure s) = s'
val : Seq1 (Option α)
⊢ match
    match
      match some val with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    some val with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]
cases' val with o s'
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s'✝ s : Seq (Option α)
h : flatten (Computation.pure s) = s'✝
o : Option α
s' : Seq (Option α)
⊢ match
    match
      match some (o, s') with
      | none => none
      | some (a, b) => some (a, Computation.pure b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          Seq.corec
            (fun c =>
              match Computation.destruct c with
              | Sum.inl s =>
                match Seq.destruct s with
                | none => none
                | some (a, b) => some (a, Computation.pure b)
              | Sum.inr c' => some (none, c'))
            b),
    some (o, s') with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      Seq.corec
          (fun c =>
            match Computation.destruct c with
            | Sum.inl s =>
              match Seq.destruct s with
              | none => none
              | some (a, b) => some (a, Computation.pure b)
            | Sum.inr c' => some (none, c'))
          (Computation.pure s') =
        s
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ Seq.destruct (flatten (Computation.think c)) = some (none, flatten c)
[PROOFSTEP]
simp [flatten, think]
[GOAL]
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ destruct (flatten c) = c >>= destruct
[PROOFSTEP]
refine'
  Computation.eq_of_bisim (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct) _
    (Or.inr ⟨c, rfl, rfl⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
⊢ Computation.IsBisimulation fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
[PROOFSTEP]
intro c1 c2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
exact
  match c1, c2, h with
  | c, _, Or.inl rfl => by cases c.destruct <;> simp
  | _, _, Or.inr ⟨c, rfl, rfl⟩ =>
    by
    induction' c using Computation.recOn with a c' <;> simp
    · cases (destruct a).destruct <;> simp
    · exact Or.inr ⟨c', rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c : Computation (Option (α × WSeq α))
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Computation.destruct c) (Computation.destruct c)
[PROOFSTEP]
cases c.destruct
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c : Computation (Option (α × WSeq α))
val✝ : Option (α × WSeq α)
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Sum.inl val✝) (Sum.inl val✝)
[PROOFSTEP]
simp
[GOAL]
case inr
α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c val✝ : Computation (Option (α × WSeq α))
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Sum.inr val✝) (Sum.inr val✝)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
c✝ : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c : Computation (WSeq α)
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Computation.destruct (destruct (flatten c))) (Computation.destruct (Computation.bind c destruct))
[PROOFSTEP]
induction' c using Computation.recOn with a c'
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
a : WSeq α
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Computation.destruct (destruct (flatten (Computation.pure a))))
    (Computation.destruct (Computation.bind (Computation.pure a) destruct))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c' : Computation (WSeq α)
⊢ Computation.BisimO (fun c1 c2 => c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct)
    (Computation.destruct (destruct (flatten (Computation.think c'))))
    (Computation.destruct (Computation.bind (Computation.think c') destruct))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
a : WSeq α
⊢ match Computation.destruct (destruct a), Computation.destruct (destruct a) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => s = s' ∨ ∃ c, s = destruct (flatten c) ∧ s' = Computation.bind c destruct
  | x, x_1 => False
[PROOFSTEP]
cases (destruct a).destruct
[GOAL]
case h1.inl
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
a : WSeq α
val✝ : Option (α × WSeq α)
⊢ match Sum.inl val✝, Sum.inl val✝ with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => s = s' ∨ ∃ c, s = destruct (flatten c) ∧ s' = Computation.bind c destruct
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.inr
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
a : WSeq α
val✝ : Computation (Option (α × WSeq α))
⊢ match Sum.inr val✝, Sum.inr val✝ with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' => s = s' ∨ ∃ c, s = destruct (flatten c) ∧ s' = Computation.bind c destruct
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ c, c1 = destruct (flatten c) ∧ c2 = Computation.bind c destruct
c' : Computation (WSeq α)
⊢ destruct (flatten c') = Computation.bind c' destruct ∨
    ∃ c, destruct (flatten c') = destruct (flatten c) ∧ Computation.bind c' destruct = Computation.bind c destruct
[PROOFSTEP]
exact Or.inr ⟨c', rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
⊢ tail nil = nil
[PROOFSTEP]
simp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ tail (cons a s) = s
[PROOFSTEP]
simp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ tail (think s) = think (tail s)
[PROOFSTEP]
simp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
n : ℕ
⊢ drop nil n = nil
[PROOFSTEP]
induction n
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
⊢ drop nil Nat.zero = nil
[PROOFSTEP]
simp [*, drop]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
n✝ : ℕ
n_ih✝ : drop nil n✝ = nil
⊢ drop nil (Nat.succ n✝) = nil
[PROOFSTEP]
simp [*, drop]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
n : ℕ
⊢ drop (cons a s) (n + 1) = drop s n
[PROOFSTEP]
induction n with
| zero => simp [drop]
| succ n n_ih =>
  -- Porting note: Was `simp [*, drop]`.simp [drop, ← n_ih]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
n : ℕ
⊢ drop (cons a s) (n + 1) = drop s n
[PROOFSTEP]
induction n with
| zero => simp [drop]
| succ n n_ih =>
  -- Porting note: Was `simp [*, drop]`.simp [drop, ← n_ih]
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ drop (cons a s) (Nat.zero + 1) = drop s Nat.zero
[PROOFSTEP]

| zero => simp [drop]
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ drop (cons a s) (Nat.zero + 1) = drop s Nat.zero
[PROOFSTEP]
simp [drop]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
n : ℕ
n_ih : drop (cons a s) (n + 1) = drop s n
⊢ drop (cons a s) (Nat.succ n + 1) = drop s (Nat.succ n)
[PROOFSTEP]

| succ n n_ih =>
  -- Porting note: Was `simp [*, drop]`.simp [drop, ← n_ih]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
n : ℕ
n_ih : drop (cons a s) (n + 1) = drop s n
⊢ drop (cons a s) (Nat.succ n + 1) = drop s (Nat.succ n)
[PROOFSTEP]
simp [drop, ← n_ih]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ drop (think s) n = think (drop s n)
[PROOFSTEP]
induction n
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ drop (think s) Nat.zero = think (drop s Nat.zero)
[PROOFSTEP]
simp [*, drop]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n✝ : ℕ
n_ih✝ : drop (think s) n✝ = think (drop s n✝)
⊢ drop (think s) (Nat.succ n✝) = think (drop s (Nat.succ n✝))
[PROOFSTEP]
simp [*, drop]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ drop (tail s) n = drop s (n + 1)
[PROOFSTEP]
rw [add_comm]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ drop (tail s) n = drop s (1 + n)
[PROOFSTEP]
symm
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ drop s (1 + n) = drop (tail s) n
[PROOFSTEP]
apply dropn_add
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
⊢ join (think S) = think (join S)
[PROOFSTEP]
simp [think, join]
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
⊢ Seq.join
      ((fun o =>
          match o with
          | none => Seq1.ret none
          | some s => (none, s)) <$>
        Seq.cons none S) =
    Seq.cons none
      (Seq.join
        ((fun o =>
            match o with
            | none => Seq1.ret none
            | some s => (none, s)) <$>
          S))
[PROOFSTEP]
dsimp only [(· <$> ·)]
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
⊢ Seq.join
      (Seq.map
        (fun o =>
          match o with
          | none => Seq1.ret none
          | some s => (none, s))
        (Seq.cons none S)) =
    Seq.cons none
      (Seq.join
        (Seq.map
          (fun o =>
            match o with
            | none => Seq1.ret none
            | some s => (none, s))
          S))
[PROOFSTEP]
simp [join, Seq1.ret]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
S : WSeq (WSeq α)
⊢ join (cons s S) = think (append s (join S))
[PROOFSTEP]
simp [think, join]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
S : WSeq (WSeq α)
⊢ Seq.join
      ((fun o =>
          match o with
          | none => Seq1.ret none
          | some s => (none, s)) <$>
        cons s S) =
    Seq.cons none
      (append s
        (Seq.join
          ((fun o =>
              match o with
              | none => Seq1.ret none
              | some s => (none, s)) <$>
            S)))
[PROOFSTEP]
dsimp only [(· <$> ·)]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
S : WSeq (WSeq α)
⊢ Seq.join
      (Seq.map
        (fun o =>
          match o with
          | none => Seq1.ret none
          | some s => (none, s))
        (cons s S)) =
    Seq.cons none
      (append s
        (Seq.join
          (Seq.map
            (fun o =>
              match o with
              | none => Seq1.ret none
              | some s => (none, s))
            S)))
[PROOFSTEP]
simp [join, cons, append]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ destruct (tail s) = destruct s >>= tail.aux
[PROOFSTEP]
simp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ (fun o => Option.rec nil Prod.snd o) <$> destruct s >>= destruct = do
    let x ← destruct s
    match x with
      | none => Computation.pure none
      | some (fst, s) => destruct s
[PROOFSTEP]
rw [← bind_pure_comp, LawfulMonad.bind_assoc]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ (destruct s >>= fun x => Pure.pure (Option.rec nil Prod.snd x) >>= destruct) = do
    let x ← destruct s
    match x with
      | none => Computation.pure none
      | some (fst, s) => destruct s
[PROOFSTEP]
apply congr_arg
[GOAL]
case h
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ (fun x => Pure.pure (Option.rec nil Prod.snd x) >>= destruct) = fun x =>
    match x with
    | none => Computation.pure none
    | some (fst, s) => destruct s
[PROOFSTEP]
ext1 (_ | ⟨a, s⟩)
[GOAL]
case h.h.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ Pure.pure (Option.rec nil Prod.snd none) >>= destruct =
    match none with
    | none => Computation.pure none
    | some (fst, s) => destruct s
[PROOFSTEP]
apply (@pure_bind Computation _ _ _ _ _ _).trans _
[GOAL]
case h.h.some.mk
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
a : α
s : WSeq α
⊢ Pure.pure (Option.rec nil Prod.snd (some (a, s))) >>= destruct =
    match some (a, s) with
    | none => Computation.pure none
    | some (fst, s) => destruct s
[PROOFSTEP]
apply (@pure_bind Computation _ _ _ _ _ _).trans _
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ destruct (Option.rec nil Prod.snd none) =
    match none with
    | none => Computation.pure none
    | some (fst, s) => destruct s
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
a : α
s : WSeq α
⊢ destruct (Option.rec nil Prod.snd (some (a, s))) =
    match some (a, s) with
    | none => Computation.pure none
    | some (fst, s) => destruct s
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
n : ℕ
⊢ Computation.bind (Computation.pure none) (aux n) = Computation.pure none
[PROOFSTEP]
rw [ret_bind, drop.aux_none n]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ destruct (drop s (n + 1)) = destruct s >>= drop.aux (n + 1)
[PROOFSTEP]
rw [← dropn_tail, destruct_dropn _ n, destruct_tail, LawfulMonad.bind_assoc]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
⊢ (destruct s >>= fun x => tail.aux x >>= drop.aux n) = destruct s >>= drop.aux (n + 1)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
T : Terminates (head (tail s))
⊢ Terminates (destruct s)
[PROOFSTEP]
rcases(head_terminates_iff _).1 T with ⟨⟨a, h⟩⟩
[GOAL]
case mk.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
T : Terminates (head (tail s))
a : Option (α × WSeq α)
h : a ∈ destruct (tail s)
⊢ Terminates (destruct s)
[PROOFSTEP]
simp [tail] at h 
[GOAL]
case mk.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
T : Terminates (head (tail s))
a : Option (α × WSeq α)
h : a ∈ (fun o => Option.rec nil Prod.snd o) <$> destruct s >>= destruct
⊢ Terminates (destruct s)
[PROOFSTEP]
rcases exists_of_mem_bind h with ⟨s', h1, _⟩
[GOAL]
case mk.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
T : Terminates (head (tail s))
a : Option (α × WSeq α)
h : a ∈ (fun o => Option.rec nil Prod.snd o) <$> destruct s >>= destruct
s' : WSeq α
h1 : s' ∈ (fun o => Option.rec nil Prod.snd o) <$> destruct s
right✝ : a ∈ destruct s'
⊢ Terminates (destruct s)
[PROOFSTEP]
unfold Functor.map at h1 
[GOAL]
case mk.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
T : Terminates (head (tail s))
a : Option (α × WSeq α)
h : a ∈ (fun o => Option.rec nil Prod.snd o) <$> destruct s >>= destruct
s' : WSeq α
h1 : s' ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s)
right✝ : a ∈ destruct s'
⊢ Terminates (destruct s)
[PROOFSTEP]
exact
  let ⟨t, h3, _⟩ := Computation.exists_of_mem_map h1
  Computation.terminates_of_mem h3
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
h : some a ∈ destruct (tail s)
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
unfold tail Functor.map at h 
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
h : some a ∈ destruct (flatten (Applicative.toFunctor.1 (fun o => Option.recOn o nil Prod.snd) (destruct s)))
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
simp at h 
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
h : some a ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s) >>= destruct
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
rcases exists_of_mem_bind h with ⟨t, tm, td⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
h : some a ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s) >>= destruct
t : WSeq α
tm : t ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s)
td : some a ∈ destruct t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
clear h
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
tm : t ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s)
td : some a ∈ destruct t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
rcases Computation.exists_of_mem_map tm with ⟨t', ht', ht2⟩
[GOAL]
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
tm : t ∈ Applicative.toFunctor.1 (fun o => Option.rec nil Prod.snd o) (destruct s)
td : some a ∈ destruct t
t' : Option (α × WSeq α)
ht' : t' ∈ destruct s
ht2 : Option.rec nil Prod.snd t' = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
clear tm
[GOAL]
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
td : some a ∈ destruct t
t' : Option (α × WSeq α)
ht' : t' ∈ destruct s
ht2 : Option.rec nil Prod.snd t' = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
cases' t' with t'
[GOAL]
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
td : some a ∈ destruct t
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
rw [← ht2] at td 
[GOAL]
case intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
td : some a ∈ destruct t
t' : α × WSeq α
ht' : some t' ∈ destruct s
ht2 : Option.rec nil Prod.snd (some t') = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
rw [← ht2] at td 
[GOAL]
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
td : some a ∈ destruct (Option.rec nil Prod.snd none)
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
simp at td 
[GOAL]
case intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
t' : α × WSeq α
td : some a ∈ destruct (Option.rec nil Prod.snd (some t'))
ht' : some t' ∈ destruct s
ht2 : Option.rec nil Prod.snd (some t') = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
simp at td 
[GOAL]
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
td : some a ∈ Computation.pure none
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
have := mem_unique td (ret_mem _)
[GOAL]
case intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
ht' : none ∈ destruct s
ht2 : Option.rec nil Prod.snd none = t
td : some a ∈ Computation.pure none
this : some a = none
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
contradiction
[GOAL]
case intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α × WSeq α
t : WSeq α
t' : α × WSeq α
td : some a ∈ destruct t'.snd
ht' : some t' ∈ destruct s
ht2 : Option.rec nil Prod.snd (some t') = t
⊢ ∃ a', some a' ∈ destruct s
[PROOFSTEP]
exact ⟨_, ht'⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ head (tail s)
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
unfold head at h 
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (tail s))
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
rcases Computation.exists_of_mem_map h with ⟨o, md, e⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (tail s))
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
clear h
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
cases' o with o <;> [injection e; injection e with h']
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : Option (α × WSeq α)
md : o ∈ destruct (tail s)
e : Prod.fst <$> o = some a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
cases' o with o
[GOAL]
case intro.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
md : none ∈ destruct (tail s)
e : Prod.fst <$> none = some a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
injection e
[GOAL]
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
e : Prod.fst <$> some o = some a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
injection e with h'
[GOAL]
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
h' : o.fst = a
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
clear h'
[GOAL]
case intro.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
cases' destruct_some_of_destruct_tail_some md with a am
[GOAL]
case intro.intro.some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a✝ : α
o : α × WSeq α
md : some o ∈ destruct (tail s)
a : α × WSeq α
am : some a ∈ destruct s
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
exact ⟨_, Computation.mem_map (@Prod.fst α (WSeq α) <$> ·) am⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
n : ℕ
h : some a ∈ get? s n
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
induction n generalizing a with
| zero => exact ⟨_, h⟩
| succ n IH =>
  let ⟨a', h'⟩ := head_some_of_head_tail_some h
  exact IH h'
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
n : ℕ
h : some a ∈ get? s n
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
induction n generalizing a with
| zero => exact ⟨_, h⟩
| succ n IH =>
  let ⟨a', h'⟩ := head_some_of_head_tail_some h
  exact IH h'
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ get? s Nat.zero
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]

| zero => exact ⟨_, h⟩
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : some a ∈ get? s Nat.zero
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
exact ⟨_, h⟩
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]

| succ n IH =>
  let ⟨a', h'⟩ := head_some_of_head_tail_some h
  exact IH h'
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
let ⟨a', h'⟩ := head_some_of_head_tail_some h
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s : WSeq α
n : ℕ
IH : ∀ {a : α}, some a ∈ get? s n → ∃ a', some a' ∈ head s
a : α
h : some a ∈ get? s (Nat.succ n)
a' : α
h' : some a' ∈ head (drop s n)
⊢ ∃ a', some a' ∈ head s
[PROOFSTEP]
exact IH h'
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
⊢ Terminates (get? (tail s) n)
[PROOFSTEP]
rw [get?_tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
⊢ Terminates (get? s (n + 1))
[PROOFSTEP]
infer_instance
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n m : ℕ
⊢ Terminates (get? (drop s n) m)
[PROOFSTEP]
rw [← get?_add]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n m : ℕ
⊢ Terminates (get? s (n + m))
[PROOFSTEP]
infer_instance
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
cases e : Computation.get (get? s (n + 1))
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
e : Computation.get (get? s (n + 1)) = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
assumption
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
have := mem_of_get_eq _ e
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : (fun n => Computation.get (get? s n)) n = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ get? s (n + 1)
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
simp [get?] at this h 
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ head (drop s (n + 1))
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
cases' head_some_of_head_tail_some this with a' h'
[GOAL]
case some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this : some val✝ ∈ head (drop s (n + 1))
a' : α
h' : some a' ∈ head (drop s (Nat.add n 0))
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
have := mem_unique h' (@mem_of_get_eq _ _ _ _ h)
[GOAL]
case some.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
inst✝ : Productive s
n : ℕ
h : Computation.get (head (drop s n)) = none
val✝ : α
e : Computation.get (get? s (n + 1)) = some val✝
this✝ : some val✝ ∈ head (drop s (n + 1))
a' : α
h' : some a' ∈ head (drop s (Nat.add n 0))
this : some a' = none
⊢ (fun n => Computation.get (get? s n)) (n + 1) = none
[PROOFSTEP]
contradiction
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n : ℕ
h : m ≤ n
⊢ Terminates (get? s n) → Terminates (get? s m)
[PROOFSTEP]
induction' h with m' _ IH
[GOAL]
case refl
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n : ℕ
⊢ Terminates (get? s m) → Terminates (get? s m)
case step
α : Type u
β : Type v
γ : Type w
s : WSeq α
m n m' : ℕ
a✝ : Nat.le m m'
IH : Terminates (get? s m') → Terminates (get? s m)
⊢ Terminates (get? s (Nat.succ m')) → Terminates (get? s m)
[PROOFSTEP]
exacts [id, fun T => IH (@head_terminates_of_head_tail_terminates _ _ T)]
[GOAL]
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
⊢ C s
[PROOFSTEP]
apply Seq.mem_rec_on M
[GOAL]
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
⊢ ∀ (b : Option α) (s' : Seq (Option α)), some a = b ∨ C s' → C (Seq.cons b s')
[PROOFSTEP]
intro o s' h
[GOAL]
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
o : Option α
s' : Seq (Option α)
h : some a = o ∨ C s'
⊢ C (Seq.cons o s')
[PROOFSTEP]
cases' o with b
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h : some a = none ∨ C s'
⊢ C (Seq.cons none s')
[PROOFSTEP]
apply h2
[GOAL]
case none.a
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h : some a = none ∨ C s'
⊢ C s'
[PROOFSTEP]
cases h
[GOAL]
case none.a.inl
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h✝ : some a = none
⊢ C s'
[PROOFSTEP]
contradiction
[GOAL]
case none.a.inr
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
h✝ : C s'
⊢ C s'
[PROOFSTEP]
assumption
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ C (Seq.cons (some b) s')
[PROOFSTEP]
apply h1
[GOAL]
case some.a
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ a = b ∨ C s'
[PROOFSTEP]
apply Or.imp_left _ h
[GOAL]
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h : some a = some b ∨ C s'
⊢ some a = some b → a = b
[PROOFSTEP]
intro h
[GOAL]
α : Type u
β : Type v
γ : Type w
C : WSeq α → Prop
a : α
s : WSeq α
M : a ∈ s
h1 : ∀ (b : α) (s' : WSeq α), a = b ∨ C s' → C (cons b s')
h2 : ∀ (s : WSeq α), C s → C (think s)
s' : Seq (Option α)
b : α
h✝ : some a = some b ∨ C s'
h : some a = some b
⊢ a = b
[PROOFSTEP]
injection h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
⊢ a ∈ think s ↔ a ∈ s
[PROOFSTEP]
cases' s with f al
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ a ∈ think { val := f, property := al } ↔ a ∈ { val := f, property := al }
[PROOFSTEP]
change (some (some a) ∈ some none :: f) ↔ some (some a) ∈ f
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ some none :: f ↔ some (some a) ∈ f
[PROOFSTEP]
constructor
[GOAL]
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ some none :: f → some (some a) ∈ f
[PROOFSTEP]
intro h
[GOAL]
case mk.mpr
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
⊢ some (some a) ∈ f → some (some a) ∈ some none :: f
[PROOFSTEP]
intro h
[GOAL]
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ some none :: f
⊢ some (some a) ∈ f
[PROOFSTEP]
apply (Stream'.eq_or_mem_of_mem_cons h).resolve_left
[GOAL]
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ some none :: f
⊢ ¬some (some a) = some none
[PROOFSTEP]
intro
[GOAL]
case mk.mp
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ some none :: f
a✝ : some (some a) = some none
⊢ False
[PROOFSTEP]
injections
[GOAL]
case mk.mpr
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option (Option α))
al : IsSeq f
h : some (some a) ∈ f
⊢ some (some a) ∈ some none :: f
[PROOFSTEP]
apply Stream'.mem_cons_of_mem _ h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a a' : α
s' : WSeq α
⊢ some (a', s') ∈ destruct s → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
generalize e : destruct s = c
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
e : destruct s = c
⊢ some (a', s') ∈ c → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
e : destruct s = c
h : some (a', s') ∈ c
⊢ a ∈ s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
revert s
[GOAL]
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
apply Computation.memRecOn h <;> [skip; intro c IH]
[GOAL]
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
apply Computation.memRecOn h
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ ∀ {s : WSeq α}, destruct s = Computation.pure (some (a', s')) → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
skip
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ ∀ (s : Computation (Option (α × WSeq α))),
    (∀ {s_1 : WSeq α}, destruct s_1 = s → (a ∈ s_1 ↔ a = a' ∨ a ∈ s')) →
      ∀ {s_1 : WSeq α}, destruct s_1 = Computation.think s → (a ∈ s_1 ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro c IH
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ ∀ {s : WSeq α}, destruct s = Computation.pure (some (a', s')) → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
⊢ ∀ {s : WSeq α}, destruct s = Computation.think c → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
s : WSeq α
⊢ destruct s = Computation.pure (some (a', s')) → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
induction' s using WSeq.recOn with x s s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
s : WSeq α
⊢ destruct s = Computation.think c → (a ∈ s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
induction' s using WSeq.recOn with x s s
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
⊢ destruct nil = Computation.pure (some (a', s')) → (a ∈ nil ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
⊢ destruct (cons x s) = Computation.pure (some (a', s')) → (a ∈ cons x s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
s : WSeq α
⊢ destruct (think s) = Computation.pure (some (a', s')) → (a ∈ think s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h2.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
⊢ destruct nil = Computation.think c → (a ∈ nil ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
x : α
s : WSeq α
⊢ destruct (cons x s) = Computation.think c → (a ∈ cons x s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
s : WSeq α
⊢ destruct (think s) = Computation.think c → (a ∈ think s ↔ a = a' ∨ a ∈ s')
[PROOFSTEP]
intro m
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
m : destruct nil = Computation.pure (some (a', s'))
⊢ a ∈ nil ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
m : destruct (cons x s) = Computation.pure (some (a', s'))
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
s : WSeq α
m : destruct (think s) = Computation.pure (some (a', s'))
⊢ a ∈ think s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h2.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
m : destruct nil = Computation.think c
⊢ a ∈ nil ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
x : α
s : WSeq α
m : destruct (cons x s) = Computation.think c
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
s : WSeq α
m : destruct (think s) = Computation.think c
⊢ a ∈ think s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
have := congr_arg Computation.destruct m
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
m : destruct nil = Computation.pure (some (a', s'))
this : Computation.destruct (destruct nil) = Computation.destruct (Computation.pure (some (a', s')))
⊢ a ∈ nil ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
m : destruct (cons x s) = Computation.pure (some (a', s'))
this : Computation.destruct (destruct (cons x s)) = Computation.destruct (Computation.pure (some (a', s')))
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
s : WSeq α
m : destruct (think s) = Computation.pure (some (a', s'))
this : Computation.destruct (destruct (think s)) = Computation.destruct (Computation.pure (some (a', s')))
⊢ a ∈ think s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h1
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
m : destruct nil = Computation.think c
this : Computation.destruct (destruct nil) = Computation.destruct (Computation.think c)
⊢ a ∈ nil ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
x : α
s : WSeq α
m : destruct (cons x s) = Computation.think c
this : Computation.destruct (destruct (cons x s)) = Computation.destruct (Computation.think c)
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
s : WSeq α
m : destruct (think s) = Computation.think c
this : Computation.destruct (destruct (think s)) = Computation.destruct (Computation.think c)
⊢ a ∈ think s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
m : destruct (cons x s) = Computation.pure (some (a', s'))
this : x = a' ∧ s = s'
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
cases' this with i1 i2
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
m : destruct (cons x s) = Computation.pure (some (a', s'))
i1 : x = a'
i2 : s = s'
⊢ a ∈ cons x s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
rw [i1, i2]
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c
x : α
s : WSeq α
m : destruct (cons x s) = Computation.pure (some (a', s'))
i1 : x = a'
i2 : s = s'
⊢ a ∈ cons a' s' ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
cases' s' with f al
[GOAL]
case h1.h2.intro.mk
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
⊢ a ∈ cons a' { val := f, property := al } ↔ a = a' ∨ a ∈ { val := f, property := al }
[PROOFSTEP]
dsimp only [cons, (· ∈ ·), WSeq.Mem, Seq.Mem, Seq.cons]
[GOAL]
case h1.h2.intro.mk
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
⊢ Any (fun b => some (some a) = b) (some (some a') :: f) ↔ a = a' ∨ Any (fun b => some (some a) = b) f
[PROOFSTEP]
have h_a_eq_a' : a = a' ↔ some (some a) = some (some a') := by simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
⊢ a = a' ↔ some (some a) = some (some a')
[PROOFSTEP]
simp
[GOAL]
case h1.h2.intro.mk
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
⊢ Any (fun b => some (some a) = b) (some (some a') :: f) ↔ a = a' ∨ Any (fun b => some (some a) = b) f
[PROOFSTEP]
rw [h_a_eq_a']
[GOAL]
case h1.h2.intro.mk
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
⊢ Any (fun b => some (some a) = b) (some (some a') :: f) ↔
    some (some a) = some (some a') ∨ Any (fun b => some (some a) = b) f
[PROOFSTEP]
refine' ⟨Stream'.eq_or_mem_of_mem_cons, fun o => _⟩
[GOAL]
case h1.h2.intro.mk
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
o : some (some a) = some (some a') ∨ Any (fun b => some (some a) = b) f
⊢ Any (fun b => some (some a) = b) (some (some a') :: f)
[PROOFSTEP]
cases' o with e m
[GOAL]
case h1.h2.intro.mk.inl
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
e : some (some a) = some (some a')
⊢ Any (fun b => some (some a) = b) (some (some a') :: f)
[PROOFSTEP]
rw [e]
[GOAL]
case h1.h2.intro.mk.inl
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
e : some (some a) = some (some a')
⊢ Any (fun b => some (some a') = b) (some (some a') :: f)
[PROOFSTEP]
apply Stream'.mem_cons
[GOAL]
case h1.h2.intro.mk.inr
α : Type u
β : Type v
γ : Type w
a a' : α
c : Computation (Option (α × WSeq α))
x : α
s : WSeq α
i1 : x = a'
f : Stream' (Option (Option α))
al : IsSeq f
h : some (a', { val := f, property := al }) ∈ c
m✝ : destruct (cons x s) = Computation.pure (some (a', { val := f, property := al }))
i2 : s = { val := f, property := al }
h_a_eq_a' : a = a' ↔ some (some a) = some (some a')
m : Any (fun b => some (some a) = b) f
⊢ Any (fun b => some (some a) = b) (some (some a') :: f)
[PROOFSTEP]
exact Stream'.mem_cons_of_mem _ m
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a a' : α
s' : WSeq α
c✝ : Computation (Option (α × WSeq α))
h : some (a', s') ∈ c✝
c : Computation (Option (α × WSeq α))
IH : ∀ {s : WSeq α}, destruct s = c → (a ∈ s ↔ a = a' ∨ a ∈ s')
s : WSeq α
m : destruct (think s) = Computation.think c
this : destruct s = c
⊢ a ∈ think s ↔ a = a' ∨ a ∈ s'
[PROOFSTEP]
simp [IH this]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
b a : α
⊢ some (b, s) ∈ destruct (cons b s)
[PROOFSTEP]
simp [ret_mem]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
⊢ a ∈ tail s → a ∈ s
[PROOFSTEP]
intro h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : a ∈ tail s
⊢ a ∈ s
[PROOFSTEP]
have := h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h this : a ∈ tail s
⊢ a ∈ s
[PROOFSTEP]
cases' h with n e
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
this : a ∈ tail s
n : ℕ
e : (fun b => some (some a) = b) (nth (↑(tail s)) n)
⊢ a ∈ s
[PROOFSTEP]
revert s
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
⊢ ∀ {s : WSeq α}, a ∈ tail s → (fun b => some (some a) = b) (nth (↑(tail s)) n) → a ∈ s
[PROOFSTEP]
simp [Stream'.nth]
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
⊢ ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
[PROOFSTEP]
induction' n with n IH
[GOAL]
case intro.zero
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) Nat.zero → a ∈ s
[PROOFSTEP]
intro s
[GOAL]
case intro.succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
⊢ ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) (Nat.succ n) → a ∈ s
[PROOFSTEP]
intro s
[GOAL]
case intro.zero
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ a ∈ tail s → some (some a) = ↑(tail s) Nat.zero → a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with x s s
[GOAL]
case intro.succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
⊢ a ∈ tail s → some (some a) = ↑(tail s) (Nat.succ n) → a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with x s s
[GOAL]
case intro.zero.h1
α : Type u
β : Type v
γ : Type w
a : α
⊢ a ∈ tail nil → some (some a) = ↑(tail nil) Nat.zero → a ∈ nil
[PROOFSTEP]
simp
[GOAL]
case intro.zero.h2
α : Type u
β : Type v
γ : Type w
a x : α
s : WSeq α
⊢ a ∈ tail (cons x s) → some (some a) = ↑(tail (cons x s)) Nat.zero → a ∈ cons x s
[PROOFSTEP]
simp
[GOAL]
case intro.zero.h3
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ a ∈ tail (think s) → some (some a) = ↑(tail (think s)) Nat.zero → a ∈ think s
[PROOFSTEP]
simp
[GOAL]
case intro.succ.h1
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
⊢ a ∈ tail nil → some (some a) = ↑(tail nil) (Nat.succ n) → a ∈ nil
[PROOFSTEP]
simp
[GOAL]
case intro.succ.h2
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
x : α
s : WSeq α
⊢ a ∈ tail (cons x s) → some (some a) = ↑(tail (cons x s)) (Nat.succ n) → a ∈ cons x s
[PROOFSTEP]
simp
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
⊢ a ∈ tail (think s) → some (some a) = ↑(tail (think s)) (Nat.succ n) → a ∈ think s
[PROOFSTEP]
simp
[GOAL]
case intro.zero.h1
α : Type u
β : Type v
γ : Type w
a : α
⊢ a ∈ nil → some (some a) = ↑nil 0 → a ∈ nil
[PROOFSTEP]
intro m e
[GOAL]
case intro.zero.h2
α : Type u
β : Type v
γ : Type w
a x : α
s : WSeq α
⊢ a ∈ s → some (some a) = ↑s 0 → a = x ∨ a ∈ s
[PROOFSTEP]
intro m e
[GOAL]
case intro.zero.h3
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ a ∈ tail s → some (some a) = ↑(think (tail s)) 0 → a ∈ s
[PROOFSTEP]
intro m e
[GOAL]
case intro.succ.h1
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
⊢ a ∈ nil → some (some a) = ↑nil (Nat.succ n) → a ∈ nil
[PROOFSTEP]
intro m e
[GOAL]
case intro.succ.h2
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
x : α
s : WSeq α
⊢ a ∈ s → some (some a) = ↑s (Nat.succ n) → a = x ∨ a ∈ s
[PROOFSTEP]
intro m e
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
⊢ a ∈ tail s → some (some a) = ↑(think (tail s)) (Nat.succ n) → a ∈ s
[PROOFSTEP]
intro m e
[GOAL]
case intro.zero.h1
α : Type u
β : Type v
γ : Type w
a : α
m : a ∈ nil
e : some (some a) = ↑nil 0
⊢ a ∈ nil
[PROOFSTEP]
injections
[GOAL]
case intro.zero.h2
α : Type u
β : Type v
γ : Type w
a x : α
s : WSeq α
m : a ∈ s
e : some (some a) = ↑s 0
⊢ a = x ∨ a ∈ s
[PROOFSTEP]
injections
[GOAL]
case intro.zero.h3
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) 0
⊢ a ∈ s
[PROOFSTEP]
injections
[GOAL]
case intro.succ.h1
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
m : a ∈ nil
e : some (some a) = ↑nil (Nat.succ n)
⊢ a ∈ nil
[PROOFSTEP]
injections
[GOAL]
case intro.succ.h2
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
x : α
s : WSeq α
m : a ∈ s
e : some (some a) = ↑s (Nat.succ n)
⊢ a = x ∨ a ∈ s
[PROOFSTEP]
injections
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) (Nat.succ n)
⊢ a ∈ s
[PROOFSTEP]
injections
[GOAL]
case intro.zero.h2
α : Type u
β : Type v
γ : Type w
a x : α
s : WSeq α
m : a ∈ s
e : some (some a) = ↑s 0
⊢ a = x ∨ a ∈ s
[PROOFSTEP]
exact Or.inr m
[GOAL]
case intro.succ.h2
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
x : α
s : WSeq α
m : a ∈ s
e : some (some a) = ↑s (Nat.succ n)
⊢ a = x ∨ a ∈ s
[PROOFSTEP]
exact Or.inr m
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) (Nat.succ n)
⊢ a ∈ s
[PROOFSTEP]
apply IH m
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) (Nat.succ n)
⊢ some (some a) = ↑(tail s) n
[PROOFSTEP]
rw [e]
[GOAL]
case intro.succ.h3
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) (Nat.succ n)
⊢ ↑(think (tail s)) (Nat.succ n) = ↑(tail s) n
[PROOFSTEP]
cases tail s
[GOAL]
case intro.succ.h3.mk
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, a ∈ tail s → some (some a) = ↑(tail s) n → a ∈ s
s : WSeq α
m : a ∈ tail s
e : some (some a) = ↑(think (tail s)) (Nat.succ n)
val✝ : Stream' (Option (Option α))
property✝ : IsSeq val✝
⊢ ↑(think { val := val✝, property := property✝ }) (Nat.succ n) = ↑{ val := val✝, property := property✝ } n
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
n : ℕ
⊢ some a ∈ get? s n → a ∈ s
[PROOFSTEP]
revert s
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
⊢ ∀ {s : WSeq α}, some a ∈ get? s n → a ∈ s
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ {s : WSeq α}, some a ∈ get? s Nat.zero → a ∈ s
[PROOFSTEP]
intro s h
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, some a ∈ get? s n → a ∈ s
⊢ ∀ {s : WSeq α}, some a ∈ get? s (Nat.succ n) → a ∈ s
[PROOFSTEP]
intro s h
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ get? s Nat.zero
⊢ a ∈ s
[PROOFSTEP]
dsimp only [get?, head] at h 
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
⊢ a ∈ s
[PROOFSTEP]
rcases Computation.exists_of_mem_map h with ⟨o, h1, h2⟩
[GOAL]
case zero.intro.intro
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
o : Option (α × WSeq α)
h1 : o ∈ destruct (drop s Nat.zero)
h2 : Prod.fst <$> o = some a
⊢ a ∈ s
[PROOFSTEP]
cases' o with o
[GOAL]
case zero.intro.intro.none
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
h1 : none ∈ destruct (drop s Nat.zero)
h2 : Prod.fst <$> none = some a
⊢ a ∈ s
[PROOFSTEP]
injection h2
[GOAL]
case zero.intro.intro.some
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
o : α × WSeq α
h1 : some o ∈ destruct (drop s Nat.zero)
h2 : Prod.fst <$> some o = some a
⊢ a ∈ s
[PROOFSTEP]
injection h2 with h'
[GOAL]
case zero.intro.intro.some
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
o : α × WSeq α
h1 : some o ∈ destruct (drop s Nat.zero)
h' : o.fst = a
⊢ a ∈ s
[PROOFSTEP]
cases' o with a' s'
[GOAL]
case zero.intro.intro.some.mk
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s Nat.zero))
a' : α
s' : WSeq α
h1 : some (a', s') ∈ destruct (drop s Nat.zero)
h' : (a', s').fst = a
⊢ a ∈ s
[PROOFSTEP]
exact (eq_or_mem_iff_mem h1).2 (Or.inl h'.symm)
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, some a ∈ get? s n → a ∈ s
s : WSeq α
h : some a ∈ get? s (Nat.succ n)
⊢ a ∈ s
[PROOFSTEP]
have := @IH (tail s)
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, some a ∈ get? s n → a ∈ s
s : WSeq α
h : some a ∈ get? s (Nat.succ n)
this : some a ∈ get? (tail s) n → a ∈ tail s
⊢ a ∈ s
[PROOFSTEP]
rw [get?_tail] at this 
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
n : ℕ
IH : ∀ {s : WSeq α}, some a ∈ get? s n → a ∈ s
s : WSeq α
h : some a ∈ get? s (Nat.succ n)
this : some a ∈ get? s (n + 1) → a ∈ tail s
⊢ a ∈ s
[PROOFSTEP]
exact mem_of_mem_tail (this h)
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : a ∈ s
⊢ ∃ n, some a ∈ get? s n
[PROOFSTEP]
apply mem_rec_on h
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : a ∈ s
⊢ ∀ (b : α) (s' : WSeq α), (a = b ∨ ∃ n, some a ∈ get? s' n) → ∃ n, some a ∈ get? (cons b s') n
[PROOFSTEP]
intro a' s' h
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : a = a' ∨ ∃ n, some a ∈ get? s' n
⊢ ∃ n, some a ∈ get? (cons a' s') n
[PROOFSTEP]
cases' h with h h
[GOAL]
case h1.inl
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : a = a'
⊢ ∃ n, some a ∈ get? (cons a' s') n
[PROOFSTEP]
exists 0
[GOAL]
case h1.inl
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : a = a'
⊢ some a ∈ get? (cons a' s') 0
[PROOFSTEP]
simp only [get?, drop, head_cons]
[GOAL]
case h1.inl
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : a = a'
⊢ some a ∈ Computation.pure (some a')
[PROOFSTEP]
rw [h]
[GOAL]
case h1.inl
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : a = a'
⊢ some a' ∈ Computation.pure (some a')
[PROOFSTEP]
apply ret_mem
[GOAL]
case h1.inr
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
h : ∃ n, some a ∈ get? s' n
⊢ ∃ n, some a ∈ get? (cons a' s') n
[PROOFSTEP]
cases' h with n h
[GOAL]
case h1.inr.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
n : ℕ
h : some a ∈ get? s' n
⊢ ∃ n, some a ∈ get? (cons a' s') n
[PROOFSTEP]
exists
  n +
    1
      -- Porting note: Was `simp [get?]`.
[GOAL]
case h1.inr.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
a' : α
s' : WSeq α
n : ℕ
h : some a ∈ get? s' n
⊢ some a ∈ get? (cons a' s') (n + 1)
[PROOFSTEP]
simpa [get?]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h : a ∈ s
⊢ ∀ (s : WSeq α), (∃ n, some a ∈ get? s n) → ∃ n, some a ∈ get? (think s) n
[PROOFSTEP]
intro s' h
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
s' : WSeq α
h : ∃ n, some a ∈ get? s' n
⊢ ∃ n, some a ∈ get? (think s') n
[PROOFSTEP]
cases' h with n h
[GOAL]
case h2.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
s' : WSeq α
n : ℕ
h : some a ∈ get? s' n
⊢ ∃ n, some a ∈ get? (think s') n
[PROOFSTEP]
exists n
[GOAL]
case h2.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
s' : WSeq α
n : ℕ
h : some a ∈ get? s' n
⊢ some a ∈ get? (think s') n
[PROOFSTEP]
simp [get?]
[GOAL]
case h2.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
s' : WSeq α
n : ℕ
h : some a ∈ get? s' n
⊢ some a ∈ Computation.think (head (drop s' n))
[PROOFSTEP]
apply think_mem h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
rcases(head_terminates_iff _).1 ⟨⟨_, h⟩⟩ with ⟨⟨o, om⟩⟩
[GOAL]
case mk.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
o : Option (α × WSeq α)
om : o ∈ destruct (drop s n)
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
have := Computation.mem_unique (Computation.mem_map _ om) h
[GOAL]
case mk.intro
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
o : Option (α × WSeq α)
om : o ∈ destruct (drop s n)
this : Prod.fst <$> o = some a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
cases' o with o
[GOAL]
case mk.intro.none
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
om : none ∈ destruct (drop s n)
this : Prod.fst <$> none = some a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
injection this
[GOAL]
case mk.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
o : α × WSeq α
om : some o ∈ destruct (drop s n)
this : Prod.fst <$> some o = some a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
injection this with i
[GOAL]
case mk.intro.some
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
o : α × WSeq α
om : some o ∈ destruct (drop s n)
i : o.fst = a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
cases' o with a' s'
[GOAL]
case mk.intro.some.mk
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
a' : α
s' : WSeq α
om : some (a', s') ∈ destruct (drop s n)
i : (a', s').fst = a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
dsimp at i 
[GOAL]
case mk.intro.some.mk
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
a' : α
s' : WSeq α
om : some (a', s') ∈ destruct (drop s n)
i : a' = a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
rw [i] at om 
[GOAL]
case mk.intro.some.mk
α : Type u
β : Type v
γ : Type w
s : WSeq α
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
a' : α
s' : WSeq α
om : some (a, s') ∈ destruct (drop s n)
i : a' = a
⊢ ∃ s', some (a, s') ∈ destruct (drop s n)
[PROOFSTEP]
exact ⟨_, om⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct (drop s (n + 1))) (destruct (drop t (n + 1)))
[PROOFSTEP]
simp only [LiftRelO, drop, Nat.add_eq, add_zero, destruct_tail, tail.aux]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
      | x, x_2 => False)
    (do
      let x ← destruct (drop s n)
      match x with
        | none => Computation.pure none
        | some (fst, s) => destruct s)
    do
    let x ← destruct (drop t n)
    match x with
      | none => Computation.pure none
      | some (fst, s) => destruct s
[PROOFSTEP]
apply liftRel_bind
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ Computation.LiftRel ?R (destruct (drop s n)) (destruct (drop t n))
case h2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    ?R a b →
      Computation.LiftRel
        (fun x x_1 =>
          match x, x_1 with
          | none, none => True
          | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
          | x, x_2 => False)
        (match a with
        | none => Computation.pure none
        | some (fst, s) => destruct s)
        (match b with
        | none => Computation.pure none
        | some (fst, s) => destruct s)
case R
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ Option (α × WSeq α) → Option (β × WSeq β) → Prop
[PROOFSTEP]
apply liftRel_dropn_destruct H n
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      Computation.LiftRel
        (fun x x_1 =>
          match x, x_1 with
          | none, none => True
          | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
          | x, x_2 => False)
        (match a with
        | none => Computation.pure none
        | some (fst, s) => destruct s)
        (match b with
        | none => Computation.pure none
        | some (fst, s) => destruct s)
[PROOFSTEP]
exact fun {a b} o =>
  match a, b, o with
  | none, none, _ => by
    -- Porting note: These 2 theorems should be excluded.simp [-liftRel_pure_left, -liftRel_pure_right]
  | some (a, s), some (b, t), ⟨_, h2⟩ => by simp [tail.aux]; apply liftRel_destruct h2
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
n : ℕ
a : Option (α × WSeq α)
b : Option (β × WSeq β)
o : LiftRelO R (LiftRel R) a b
x✝ : LiftRelO R (LiftRel R) none none
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
      | x, x_2 => False)
    (match none with
    | none => Computation.pure none
    | some (fst, s) => destruct s)
    (match none with
    | none => Computation.pure none
    | some (fst, s) => destruct s)
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
H : LiftRel R s✝ t✝
n : ℕ
a✝ : Option (α × WSeq α)
b✝ : Option (β × WSeq β)
o : LiftRelO R (LiftRel R) a✝ b✝
a : α
s : WSeq α
b : β
t : WSeq β
left✝ : R a b
h2 : LiftRel R s t
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
      | x, x_2 => False)
    (match some (a, s) with
    | none => Computation.pure none
    | some (fst, s) => destruct s)
    (match some (b, t) with
    | none => Computation.pure none
    | some (fst, s) => destruct s)
[PROOFSTEP]
simp [tail.aux]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s✝ : WSeq α
t✝ : WSeq β
H : LiftRel R s✝ t✝
n : ℕ
a✝ : Option (α × WSeq α)
b✝ : Option (β × WSeq β)
o : LiftRelO R (LiftRel R) a✝ b✝
a : α
s : WSeq α
b : β
t : WSeq β
left✝ : R a b
h2 : LiftRel R s t
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) => R a b ∧ LiftRel R s t
      | x, x_2 => False)
    (destruct s) (destruct t)
[PROOFSTEP]
apply liftRel_destruct h2
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h : a ∈ s
⊢ ∃ b, b ∈ t ∧ R a b
[PROOFSTEP]
let ⟨n, h⟩ := exists_get?_of_mem h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ get? s n
⊢ ∃ b, b ∈ t ∧ R a b
[PROOFSTEP]
dsimp only [get?, head] at h 
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
⊢ ∃ b, b ∈ t ∧ R a b
[PROOFSTEP]
let ⟨some (_, s'), sd, rfl⟩ := Computation.exists_of_mem_map h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
s' : WSeq α
sd : some (a, s') ∈ destruct (drop s n)
⊢ ∃ b, b ∈ t ∧ R a b
[PROOFSTEP]
let ⟨some (b, t'), td, ⟨ab, _⟩⟩ := (liftRel_dropn_destruct H n).left sd
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
a : α
h✝ : a ∈ s
n : ℕ
h : some a ∈ Computation.map (fun x => Prod.fst <$> x) (destruct (drop s n))
s' : WSeq α
sd : some (a, s') ∈ destruct (drop s n)
b : β
t' : WSeq β
td : some (b, t') ∈ destruct (drop t n)
ab : R a b
right✝ : LiftRel R s' t'
⊢ ∃ b, b ∈ t ∧ R a b
[PROOFSTEP]
exact ⟨b, get?_mem (Computation.mem_map (Prod.fst.{v, v} <$> ·) td), ab⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : LiftRel R s t
b : β
h : b ∈ t
⊢ ∃ a, a ∈ s ∧ R a b
[PROOFSTEP]
rw [← LiftRel.swap] at H 
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
H : swap (LiftRel fun x y => R y x) s t
b : β
h : b ∈ t
⊢ ∃ a, a ∈ s ∧ R a b
[PROOFSTEP]
exact exists_of_liftRel_left H h
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
let ⟨o, om, oe⟩ := Seq.exists_of_mem_map h
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
o : Option α
om : o ∈ { val := g, property := al }
oe : Option.map f o = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
cases' o with a
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
om : none ∈ { val := g, property := al }
oe : Option.map f none = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
injection oe
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ { val := g, property := al }
oe : Option.map f (some a) = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
injection oe with h'
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
g : Stream' (Option (Option α))
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ { val := g, property := al }
h' : f a = b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
exact ⟨a, om, h'⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
⊢ LiftRel R nil nil
[PROOFSTEP]
rw [liftRel_destruct_iff]
  -- Porting note: These 2 theorems should be excluded.
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct nil) (destruct nil)
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
a : α
b : β
s : WSeq α
t : WSeq β
⊢ LiftRel R (cons a s) (cons b t) ↔ R a b ∧ LiftRel R s t
[PROOFSTEP]
rw [liftRel_destruct_iff]
  -- Porting note: These 2 theorems should be excluded.
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
a : α
b : β
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct (cons a s)) (destruct (cons b t)) ↔ R a b ∧ LiftRel R s t
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ LiftRel R (think s) t ↔ LiftRel R s t
[PROOFSTEP]
rw [liftRel_destruct_iff, liftRel_destruct_iff]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct (think s)) (destruct t) ↔
    Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ LiftRel R s (think t) ↔ LiftRel R s t
[PROOFSTEP]
rw [liftRel_destruct_iff, liftRel_destruct_iff]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s : WSeq α
t : WSeq β
⊢ Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct (think t)) ↔
    Computation.LiftRel (LiftRelO R (LiftRel R)) (destruct s) (destruct t)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ cons a s ~ʷ cons a t
[PROOFSTEP]
unfold Equiv
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) (cons a s) (cons a t)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
a : α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) s t
[PROOFSTEP]
exact h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ think s ~ʷ s
[PROOFSTEP]
unfold Equiv
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ LiftRel (fun x x_1 => x = x_1) (think s) s
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ LiftRel (fun x x_1 => x = x_1) s s
[PROOFSTEP]
apply Equiv.refl
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ think s ~ʷ think t
[PROOFSTEP]
unfold Equiv
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) (think s) (think t)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ LiftRel (fun x x_1 => x = x_1) s t
[PROOFSTEP]
exact h
[GOAL]
α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → head s ~ head t
[PROOFSTEP]
suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o => ⟨this h, this h.symm⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o : Option α}, o ∈ head s → o ∈ head t
[PROOFSTEP]
intro s t h o ho
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
⊢ o ∈ head t
[PROOFSTEP]
rcases@Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
⊢ o ∈ head t
[PROOFSTEP]
rw [← dse]
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
⊢ Prod.fst <$> ds ∈ head t
[PROOFSTEP]
cases' destruct_congr h with l r
[GOAL]
case intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Prod.fst <$> ds ∈ head t
[PROOFSTEP]
rcases l dsm with ⟨dt, dtm, dst⟩
[GOAL]
case intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
ds : Option (α × WSeq α)
dsm : ds ∈ destruct s
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) ds dt
⊢ Prod.fst <$> ds ∈ head t
[PROOFSTEP]
cases' ds with a
[GOAL]
case intro.intro.intro.intro.intro.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) none dt
⊢ Prod.fst <$> none ∈ head t
[PROOFSTEP]
cases' dt with b
[GOAL]
case intro.intro.intro.intro.intro.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ destruct t
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) dt
⊢ Prod.fst <$> some a ∈ head t
[PROOFSTEP]
cases' dt with b
[GOAL]
case intro.intro.intro.intro.intro.none.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
dtm : none ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none none
⊢ Prod.fst <$> none ∈ head t
[PROOFSTEP]
apply Computation.mem_map _ dtm
[GOAL]
case intro.intro.intro.intro.intro.none.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
b : α × WSeq α
dtm : some b ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none (some b)
⊢ Prod.fst <$> none ∈ head t
[PROOFSTEP]
cases b
[GOAL]
case intro.intro.intro.intro.intro.none.some.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ destruct s
dse : Prod.fst <$> none = o
fst✝ : α
snd✝ : WSeq α
dtm : some (fst✝, snd✝) ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) none (some (fst✝, snd✝))
⊢ Prod.fst <$> none ∈ head t
[PROOFSTEP]
cases dst
[GOAL]
case intro.intro.intro.intro.intro.some.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
dtm : none ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) none
⊢ Prod.fst <$> some a ∈ head t
[PROOFSTEP]
cases a
[GOAL]
case intro.intro.intro.intro.intro.some.none.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dtm : none ∈ destruct t
fst✝ : α
snd✝ : WSeq α
dsm : some (fst✝, snd✝) ∈ destruct s
dse : Prod.fst <$> some (fst✝, snd✝) = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (fst✝, snd✝)) none
⊢ Prod.fst <$> some (fst✝, snd✝) ∈ head t
[PROOFSTEP]
cases dst
[GOAL]
case intro.intro.intro.intro.intro.some.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ destruct s
dse : Prod.fst <$> some a = o
b : α × WSeq α
dtm : some b ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) (some b)
⊢ Prod.fst <$> some a ∈ head t
[PROOFSTEP]
cases' a with a s'
[GOAL]
case intro.intro.intro.intro.intro.some.some.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
b : α × WSeq α
dtm : some b ∈ destruct t
a : α
s' : WSeq α
dsm : some (a, s') ∈ destruct s
dse : Prod.fst <$> some (a, s') = o
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some b)
⊢ Prod.fst <$> some (a, s') ∈ head t
[PROOFSTEP]
cases' b with b t'
[GOAL]
case intro.intro.intro.intro.intro.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α
s' : WSeq α
dsm : some (a, s') ∈ destruct s
dse : Prod.fst <$> some (a, s') = o
b : α
t' : WSeq α
dtm : some (b, t') ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some (b, t'))
⊢ Prod.fst <$> some (a, s') ∈ head t
[PROOFSTEP]
rw [dst.left]
[GOAL]
case intro.intro.intro.intro.intro.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ head s
l : ∀ {a : Option (α × WSeq α)}, a ∈ destruct s → ∃ b, b ∈ destruct t ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ destruct t → ∃ a, a ∈ destruct s ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α
s' : WSeq α
dsm : some (a, s') ∈ destruct s
dse : Prod.fst <$> some (a, s') = o
b : α
t' : WSeq α
dtm : some (b, t') ∈ destruct t
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some (b, t'))
⊢ Prod.fst <$> some (b, s') ∈ head t
[PROOFSTEP]
exact @Computation.mem_map _ _ (@Functor.map _ _ (α × WSeq α) _ Prod.fst) (some (b, t')) (destruct t) dtm
[GOAL]
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
s : WSeq α
h : s ∈ c
⊢ flatten c ~ʷ s
[PROOFSTEP]
apply Computation.memRecOn h
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
s : WSeq α
h : s ∈ c
⊢ flatten (Computation.pure s) ~ʷ s
[PROOFSTEP]
simp [Equiv.refl]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
s : WSeq α
h : s ∈ c
⊢ ∀ (s_1 : Computation (WSeq α)), flatten s_1 ~ʷ s → flatten (Computation.think s_1) ~ʷ s
[PROOFSTEP]
intro s'
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
s : WSeq α
h : s ∈ c
s' : Computation (WSeq α)
⊢ flatten s' ~ʷ s → flatten (Computation.think s') ~ʷ s
[PROOFSTEP]
apply Equiv.trans
[GOAL]
case h2.a
α : Type u
β : Type v
γ : Type w
c : Computation (WSeq α)
s : WSeq α
h : s ∈ c
s' : Computation (WSeq α)
⊢ flatten (Computation.think s') ~ʷ flatten s'
[PROOFSTEP]
simp [think_equiv]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
⊢ Computation.LiftRel (LiftRelO R S) (destruct (flatten c1)) (destruct (flatten c2))
[PROOFSTEP]
simp [-exists_and_left]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
      | x, x_2 => False)
    (c1 >>= destruct) (c2 >>= destruct)
[PROOFSTEP]
apply liftRel_bind _ _ h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
⊢ ∀ {a : WSeq α} {b : WSeq β},
    LiftRel R a b →
      Computation.LiftRel
        (fun x x_1 =>
          match x, x_1 with
          | none, none => True
          | some (a, s), some (b, t) =>
            R a b ∧ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
          | x, x_2 => False)
        (destruct a) (destruct b)
[PROOFSTEP]
intro a b ab
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
a : WSeq α
b : WSeq β
ab : LiftRel R a b
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
      | x, x_2 => False)
    (destruct a) (destruct b)
[PROOFSTEP]
apply Computation.LiftRel.imp _ _ _ (liftRel_destruct ab)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
a : WSeq α
b : WSeq β
ab : LiftRel R a b
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      match a, b with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
      | x, x_1 => False
[PROOFSTEP]
intro a b
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ LiftRelO R (LiftRel R) a b →
    match a, b with
    | none, none => True
    | some (a, s), some (b, t) =>
      R a b ∧ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
    | x, x_1 => False
[PROOFSTEP]
apply LiftRelO.imp_right
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝¹ : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s : WSeq α
t : WSeq β
h✝ : S s t
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ ∀ (s : WSeq α) (t : WSeq β),
    LiftRel R s t → ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
[PROOFSTEP]
intro s t h
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝² : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : S s✝ t✝
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h✝ : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
[PROOFSTEP]
refine' ⟨Computation.pure s, Computation.pure t, _, _, _⟩
[GOAL]
case H.refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝² : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : S s✝ t✝
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h✝ : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ s = flatten (Computation.pure s)
[PROOFSTEP]
simp [h, -liftRel_pure_left, -liftRel_pure_right]
[GOAL]
case H.refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝² : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : S s✝ t✝
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h✝ : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ t = flatten (Computation.pure t)
[PROOFSTEP]
simp [h, -liftRel_pure_left, -liftRel_pure_right]
[GOAL]
case H.refine'_3
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
c1✝ : Computation (WSeq α)
c2✝ : Computation (WSeq β)
h✝² : Computation.LiftRel (LiftRel R) c1✝ c2✝
S : WSeq α → WSeq β → Prop :=
  fun s t => ∃ c1 c2, s = flatten c1 ∧ t = flatten c2 ∧ Computation.LiftRel (LiftRel R) c1 c2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : S s✝ t✝
c1 : Computation (WSeq α)
c2 : Computation (WSeq β)
h✝ : Computation.LiftRel (LiftRel R) c1 c2
a✝ : WSeq α
b✝ : WSeq β
ab : LiftRel R a✝ b✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ Computation.LiftRel (LiftRel R) (Computation.pure s) (Computation.pure t)
[PROOFSTEP]
simp [h, -liftRel_pure_left, -liftRel_pure_right]
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ tail s ~ʷ tail t
[PROOFSTEP]
apply flatten_congr
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ Computation.LiftRel Equiv ((fun o => Option.recOn o nil Prod.snd) <$> destruct s)
    ((fun o => Option.recOn o nil Prod.snd) <$> destruct t)
[PROOFSTEP]
dsimp only [(· <$> ·)]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ Computation.LiftRel Equiv (Computation.map (fun o => Option.rec nil Prod.snd o) (destruct s))
    (Computation.map (fun o => Option.rec nil Prod.snd o) (destruct t))
[PROOFSTEP]
rw [← Computation.bind_pure, ← Computation.bind_pure]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ Computation.LiftRel Equiv (Computation.bind (destruct s) (Computation.pure ∘ fun o => Option.rec nil Prod.snd o))
    (Computation.bind (destruct t) (Computation.pure ∘ fun o => Option.rec nil Prod.snd o))
[PROOFSTEP]
apply
  liftRel_bind _ _
    (destruct_congr h)
      -- Porting note: These 2 theorems should be excluded.
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ ∀ {a b : Option (α × WSeq α)},
    BisimO (fun x x_1 => x ~ʷ x_1) a b →
      Computation.LiftRel Equiv ((Computation.pure ∘ fun o => Option.rec nil Prod.snd o) a)
        ((Computation.pure ∘ fun o => Option.rec nil Prod.snd o) b)
[PROOFSTEP]
intro a b h
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
a b : Option (α × WSeq α)
h : BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Computation.LiftRel Equiv ((Computation.pure ∘ fun o => Option.rec nil Prod.snd o) a)
    ((Computation.pure ∘ fun o => Option.rec nil Prod.snd o) b)
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
a b : Option (α × WSeq α)
h : BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Option.rec nil Prod.snd a ~ʷ Option.rec nil Prod.snd b
[PROOFSTEP]
cases' a with a
[GOAL]
case a.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
b : Option (α × WSeq α)
h : BisimO (fun x x_1 => x ~ʷ x_1) none b
⊢ Option.rec nil Prod.snd none ~ʷ Option.rec nil Prod.snd b
[PROOFSTEP]
cases' b with b
[GOAL]
case a.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
b : Option (α × WSeq α)
a : α × WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some a) b
⊢ Option.rec nil Prod.snd (some a) ~ʷ Option.rec nil Prod.snd b
[PROOFSTEP]
cases' b with b
[GOAL]
case a.none.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
h : BisimO (fun x x_1 => x ~ʷ x_1) none none
⊢ Option.rec nil Prod.snd none ~ʷ Option.rec nil Prod.snd none
[PROOFSTEP]
trivial
[GOAL]
case a.none.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
b : α × WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) none (some b)
⊢ Option.rec nil Prod.snd none ~ʷ Option.rec nil Prod.snd (some b)
[PROOFSTEP]
cases h
[GOAL]
case a.some.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
a : α × WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some a) none
⊢ Option.rec nil Prod.snd (some a) ~ʷ Option.rec nil Prod.snd none
[PROOFSTEP]
cases a
[GOAL]
case a.some.none.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
fst✝ : α
snd✝ : WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some (fst✝, snd✝)) none
⊢ Option.rec nil Prod.snd (some (fst✝, snd✝)) ~ʷ Option.rec nil Prod.snd none
[PROOFSTEP]
cases h
[GOAL]
case a.some.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
a b : α × WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some a) (some b)
⊢ Option.rec nil Prod.snd (some a) ~ʷ Option.rec nil Prod.snd (some b)
[PROOFSTEP]
cases' a with a s'
[GOAL]
case a.some.some.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
b : α × WSeq α
a : α
s' : WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some b)
⊢ Option.rec nil Prod.snd (some (a, s')) ~ʷ Option.rec nil Prod.snd (some b)
[PROOFSTEP]
cases' b with b t'
[GOAL]
case a.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h✝ : s ~ʷ t
a : α
s' : WSeq α
b : α
t' : WSeq α
h : BisimO (fun x x_1 => x ~ʷ x_1) (some (a, s')) (some (b, t'))
⊢ Option.rec nil Prod.snd (some (a, s')) ~ʷ Option.rec nil Prod.snd (some (b, t'))
[PROOFSTEP]
exact h.right
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
n : ℕ
⊢ drop s n ~ʷ drop t n
[PROOFSTEP]
induction n
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ drop s Nat.zero ~ʷ drop t Nat.zero
[PROOFSTEP]
simp [*, tail_congr, drop]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
n✝ : ℕ
n_ih✝ : drop s n✝ ~ʷ drop t n✝
⊢ drop s (Nat.succ n✝) ~ʷ drop t (Nat.succ n✝)
[PROOFSTEP]
simp [*, tail_congr, drop]
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ Productive s ↔ Productive t
[PROOFSTEP]
simp only [productive_iff]
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
⊢ (∀ (n : ℕ), Terminates (get? s n)) ↔ ∀ (n : ℕ), Terminates (get? t n)
[PROOFSTEP]
exact forall_congr' fun n => terminates_congr <| get?_congr h _
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (destruct s)
    (destruct t)
[PROOFSTEP]
refine' liftRel_def.2 ⟨_, _⟩
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
⊢ Terminates (destruct s) ↔ Terminates (destruct t)
[PROOFSTEP]
rw [← head_terminates_iff, ← head_terminates_iff]
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
⊢ Terminates (head s) ↔ Terminates (head t)
[PROOFSTEP]
exact terminates_congr (h 0)
[GOAL]
case refine'_2
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
⊢ ∀ {a b : Option (α × WSeq α)},
    a ∈ destruct s → b ∈ destruct t → LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) a b
[PROOFSTEP]
intro a b ma mb
[GOAL]
case refine'_2
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a b : Option (α × WSeq α)
ma : a ∈ destruct s
mb : b ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) a b
[PROOFSTEP]
cases' a with a
[GOAL]
case refine'_2.none
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
b : Option (α × WSeq α)
mb : b ∈ destruct t
ma : none ∈ destruct s
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) none b
[PROOFSTEP]
cases' b with b
[GOAL]
case refine'_2.some
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
b : Option (α × WSeq α)
mb : b ∈ destruct t
a : α × WSeq α
ma : some a ∈ destruct s
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some a) b
[PROOFSTEP]
cases' b with b
[GOAL]
case refine'_2.none.none
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
ma : none ∈ destruct s
mb : none ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) none none
[PROOFSTEP]
trivial
[GOAL]
case refine'_2.none.some
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
ma : none ∈ destruct s
b : α × WSeq α
mb : some b ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) none (some b)
[PROOFSTEP]
injection mem_unique (Computation.mem_map _ ma) ((h 0 _).2 (Computation.mem_map _ mb))
[GOAL]
case refine'_2.some.none
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α × WSeq α
ma : some a ∈ destruct s
mb : none ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some a) none
[PROOFSTEP]
injection mem_unique (Computation.mem_map _ ma) ((h 0 _).2 (Computation.mem_map _ mb))
[GOAL]
case refine'_2.some.some
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α × WSeq α
ma : some a ∈ destruct s
b : α × WSeq α
mb : some b ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some a) (some b)
[PROOFSTEP]
cases' a with a s'
[GOAL]
case refine'_2.some.some.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
b : α × WSeq α
mb : some b ∈ destruct t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some (a, s')) (some b)
[PROOFSTEP]
cases' b with b t'
[GOAL]
case refine'_2.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
b : α
t' : WSeq α
mb : some (b, t') ∈ destruct t
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some (a, s')) (some (b, t'))
[PROOFSTEP]
injection mem_unique (Computation.mem_map _ ma) ((h 0 _).2 (Computation.mem_map _ mb)) with ab
[GOAL]
case refine'_2.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
b : α
t' : WSeq α
mb : some (b, t') ∈ destruct t
ab : (a, s').fst = (b, t').fst
⊢ LiftRelO (fun x x_1 => x = x_1) (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) (some (a, s')) (some (b, t'))
[PROOFSTEP]
refine' ⟨ab, fun n => _⟩
[GOAL]
case refine'_2.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
b : α
t' : WSeq α
mb : some (b, t') ∈ destruct t
ab : (a, s').fst = (b, t').fst
n : ℕ
⊢ get? s' n ~ get? t' n
[PROOFSTEP]
refine'
  (get?_congr (flatten_equiv (Computation.mem_map _ ma)) n).symm.trans
    ((_ : get? (tail s) n ~ get? (tail t) n).trans (get?_congr (flatten_equiv (Computation.mem_map _ mb)) n))
[GOAL]
case refine'_2.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
b : α
t' : WSeq α
mb : some (b, t') ∈ destruct t
ab : (a, s').fst = (b, t').fst
n : ℕ
⊢ get? (tail s) n ~ get? (tail t) n
[PROOFSTEP]
rw [get?_tail, get?_tail]
[GOAL]
case refine'_2.some.some.mk.mk
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
h✝ : ∀ (n : ℕ), get? s✝ n ~ get? t✝ n
s t : WSeq α
h : (fun s t => ∀ (n : ℕ), get? s n ~ get? t n) s t
a : α
s' : WSeq α
ma : some (a, s') ∈ destruct s
b : α
t' : WSeq α
mb : some (b, t') ∈ destruct t
ab : (a, s').fst = (b, t').fst
n : ℕ
⊢ get? s (n + 1) ~ get? t (n + 1)
[PROOFSTEP]
apply h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ length s = Computation.map List.length (toList s)
[PROOFSTEP]
refine'
  Computation.eq_of_bisim
    (fun c1 c2 =>
      ∃ (l : List α) (s : WSeq α),
        c1 =
            Computation.corec
              (fun ⟨n, s⟩ =>
                match Seq.destruct s with
                | none => Sum.inl n
                | some (none, s') => Sum.inr (n, s')
                | some (some _, s') => Sum.inr (n + 1, s'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun ⟨l, s⟩ =>
                  match Seq.destruct s with
                  | none => Sum.inl l.reverse
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    _ ⟨[], s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ Computation.IsBisimulation fun c1 c2 =>
    ∃ l s,
      c1 =
          Computation.corec
            (fun x =>
              match x with
              | (n, s) =>
                match Seq.destruct s with
                | none => Sum.inl n
                | some (none, s') => Sum.inr (n, s')
                | some (some val, s') => Sum.inr (n + 1, s'))
            (List.length l, s) ∧
        c2 =
          Computation.map List.length
            (Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l, s))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
s1 s2 : Computation ℕ
h :
  ∃ l s,
    s1 =
        Computation.corec
          (fun x =>
            match x with
            | (n, s) =>
              match Seq.destruct s with
              | none => Sum.inl n
              | some (none, s') => Sum.inr (n, s')
              | some (some val, s') => Sum.inr (n + 1, s'))
          (List.length l, s) ∧
      s2 =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match x with
              | (l, s) =>
                match Seq.destruct s with
                | none => Sum.inl (List.reverse l)
                | some (none, s') => Sum.inr (l, s')
                | some (some a, s') => Sum.inr (a :: l, s'))
            (l, s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct s1) (Computation.destruct s2)
[PROOFSTEP]
rcases h with ⟨l, s, h⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s1 s2 : Computation ℕ
l : List α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct s1) (Computation.destruct s2)
[PROOFSTEP]
rw [h.left, h.right]
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s1 s2 : Computation ℕ
l : List α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s)))
    (Computation.destruct
      (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s))))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case intro.intro.h1
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s1 s2 : Computation ℕ
l : List α
s : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s))
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, nil) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, nil))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, nil)))
    (Computation.destruct
      (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, nil))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h2
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, cons a s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, cons a s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, cons a s)))
    (Computation.destruct
      (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, cons a s))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, think s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, think s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (n, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl n
                  | some (none, s') => Sum.inr (n, s')
                  | some (some val, s') => Sum.inr (n + 1, s'))
              (List.length l, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l, s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, think s)))
    (Computation.destruct
      (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, think s))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h2
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, cons a s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, cons a s))
⊢ ∃ l_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl x.fst
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some val, s') => Sum.inr (x.fst + 1, s'))
          (List.length l + 1, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl x.fst
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some val, s') => Sum.inr (x.fst + 1, s'))
          (List.length l_1, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (a :: l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l_1, s_1))
[PROOFSTEP]
refine' ⟨a :: l, s, _, _⟩
[GOAL]
case intro.intro.h2.refine'_1
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, cons a s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, cons a s))
⊢ Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl x.fst
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some val, s') => Sum.inr (x.fst + 1, s'))
      (List.length l + 1, s) =
    Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl x.fst
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some val, s') => Sum.inr (x.fst + 1, s'))
      (List.length (a :: l), s)
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h2.refine'_2
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, cons a s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, cons a s))
⊢ Computation.map List.length
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (a :: l, s)) =
    Computation.map List.length
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (a :: l, s))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, think s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, think s))
⊢ ∃ l_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl x.fst
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some val, s') => Sum.inr (x.fst + 1, s'))
          (List.length l, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl x.fst
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some val, s') => Sum.inr (x.fst + 1, s'))
          (List.length l_1, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l_1, s_1))
[PROOFSTEP]
refine' ⟨l, s, _, _⟩
[GOAL]
case intro.intro.h3.refine'_1
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, think s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, think s))
⊢ Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl x.fst
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some val, s') => Sum.inr (x.fst + 1, s'))
      (List.length l, s) =
    Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl x.fst
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some val, s') => Sum.inr (x.fst + 1, s'))
      (List.length l, s)
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3.refine'_2
α : Type u
β : Type v
γ : Type w
s✝¹ : WSeq α
s1 s2 : Computation ℕ
l : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, s✝) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (n, s) =>
            match Seq.destruct s with
            | none => Sum.inl n
            | some (none, s') => Sum.inr (n, s')
            | some (some val, s') => Sum.inr (n + 1, s'))
        (List.length l, think s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l, think s))
⊢ Computation.map List.length
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (l, s)) =
    Computation.map List.length
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (l, s))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ Seq.map some ↑(a :: l) = Seq.cons (some a) (Seq.map some ↑l)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : WSeq α
a : α
⊢ Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l, cons a s)) =
    Sum.inr
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (a :: l, s))
[PROOFSTEP]
simp [toList, cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : WSeq α
⊢ Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l, think s)) =
    Sum.inr
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l, s))
[PROOFSTEP]
simp [toList, think]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : WSeq α
⊢ Computation.corec
      (fun x =>
        match x with
        | (l, s) =>
          match Seq.destruct s with
          | none => Sum.inl (List.reverse l)
          | some (none, s') => Sum.inr (l, s')
          | some (some a, s') => Sum.inr (a :: l, s'))
      (l, s) =
    (fun x x_1 => x ++ x_1) (List.reverse l) <$> toList s
[PROOFSTEP]
refine'
  Computation.eq_of_bisim
    (fun c1 c2 =>
      ∃ (l' : List α) (s : WSeq α),
        c1 =
            Computation.corec
              (fun ⟨l, s⟩ =>
                match Seq.destruct s with
                | none => Sum.inl l.reverse
                | some (none, s') => Sum.inr (l, s')
                | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((· ++ ·) l.reverse)
              (Computation.corec
                (fun ⟨l, s⟩ =>
                  match Seq.destruct s with
                  | none => Sum.inl l.reverse
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    _ ⟨[], s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : WSeq α
⊢ Computation.IsBisimulation fun c1 c2 =>
    ∃ l' s,
      c1 =
          Computation.corec
            (fun x =>
              match x with
              | (l, s) =>
                match Seq.destruct s with
                | none => Sum.inl (List.reverse l)
                | some (none, s') => Sum.inr (l, s')
                | some (some a, s') => Sum.inr (a :: l, s'))
            (l' ++ l, s) ∧
        c2 =
          Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
            (Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l', s))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : WSeq α
s1 s2 : Computation (List α)
h :
  ∃ l' s,
    s1 =
        Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l' ++ l, s) ∧
      s2 =
        Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
          (Computation.corec
            (fun x =>
              match x with
              | (l, s) =>
                match Seq.destruct s with
                | none => Sum.inl (List.reverse l)
                | some (none, s') => Sum.inr (l, s')
                | some (some a, s') => Sum.inr (a :: l, s'))
            (l', s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct s1) (Computation.destruct s2)
[PROOFSTEP]
rcases h with ⟨l', s, h⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
l : List α
s✝ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct s1) (Computation.destruct s2)
[PROOFSTEP]
rw [h.left, h.right]
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
l : List α
s✝ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s)))
    (Computation.destruct
      (Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s))))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case intro.intro.h1
α : Type u
β : Type v
γ : Type w
l : List α
s✝ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s))
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, nil) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', nil))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, nil)))
    (Computation.destruct
      (Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', nil))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h2
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, cons a s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', cons a s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, cons a s)))
    (Computation.destruct
      (Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', cons a s))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, think s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', think s))
⊢ Computation.BisimO
    (fun c1 c2 =>
      ∃ l' s,
        c1 =
            Computation.corec
              (fun x =>
                match x with
                | (l, s) =>
                  match Seq.destruct s with
                  | none => Sum.inl (List.reverse l)
                  | some (none, s') => Sum.inr (l, s')
                  | some (some a, s') => Sum.inr (a :: l, s'))
              (l' ++ l, s) ∧
          c2 =
            Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
              (Computation.corec
                (fun x =>
                  match x with
                  | (l, s) =>
                    match Seq.destruct s with
                    | none => Sum.inl (List.reverse l)
                    | some (none, s') => Sum.inr (l, s')
                    | some (some a, s') => Sum.inr (a :: l, s'))
                (l', s)))
    (Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, think s)))
    (Computation.destruct
      (Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', think s))))
[PROOFSTEP]
simp [toList, nil, cons, think, length]
[GOAL]
case intro.intro.h2
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, cons a s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', cons a s))
⊢ ∃ l'_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl (List.reverse x.fst)
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some a, s') => Sum.inr (a :: x.fst, s'))
          (a :: (l' ++ l), s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl (List.reverse x.fst)
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some a, s') => Sum.inr (a :: x.fst, s'))
          (l'_1 ++ l, s_1) ∧
      Computation.map (fun x => List.reverse l ++ x)
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (a :: l', s)) =
        Computation.map (fun x => List.reverse l ++ x)
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l'_1, s_1))
[PROOFSTEP]
refine' ⟨a :: l', s, _, _⟩
[GOAL]
case intro.intro.h2.refine'_1
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, cons a s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', cons a s))
⊢ Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl (List.reverse x.fst)
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some a, s') => Sum.inr (a :: x.fst, s'))
      (a :: (l' ++ l), s) =
    Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl (List.reverse x.fst)
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some a, s') => Sum.inr (a :: x.fst, s'))
      (a :: l' ++ l, s)
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h2.refine'_2
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
a : α
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, cons a s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', cons a s))
⊢ Computation.map (fun x => List.reverse l ++ x)
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (a :: l', s)) =
    Computation.map (fun x => List.reverse l ++ x)
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (a :: l', s))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, think s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', think s))
⊢ ∃ l'_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl (List.reverse x.fst)
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some a, s') => Sum.inr (a :: x.fst, s'))
          (l' ++ l, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.snd with
            | none => Sum.inl (List.reverse x.fst)
            | some (none, s') => Sum.inr (x.fst, s')
            | some (some a, s') => Sum.inr (a :: x.fst, s'))
          (l'_1 ++ l, s_1) ∧
      Computation.map (fun x => List.reverse l ++ x)
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l', s)) =
        Computation.map (fun x => List.reverse l ++ x)
          (Computation.corec
            (fun x =>
              match Seq.destruct x.snd with
              | none => Sum.inl (List.reverse x.fst)
              | some (none, s') => Sum.inr (x.fst, s')
              | some (some a, s') => Sum.inr (a :: x.fst, s'))
            (l'_1, s_1))
[PROOFSTEP]
refine' ⟨l', s, _, _⟩
[GOAL]
case intro.intro.h3.refine'_1
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, think s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', think s))
⊢ Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl (List.reverse x.fst)
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some a, s') => Sum.inr (a :: x.fst, s'))
      (l' ++ l, s) =
    Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl (List.reverse x.fst)
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some a, s') => Sum.inr (a :: x.fst, s'))
      (l' ++ l, s)
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3.refine'_2
α : Type u
β : Type v
γ : Type w
l : List α
s✝¹ : WSeq α
s1 s2 : Computation (List α)
l' : List α
s✝ : WSeq α
h✝ :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, s✝) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', s✝))
s : WSeq α
h :
  s1 =
      Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        (l' ++ l, think s) ∧
    s2 =
      Computation.map ((fun x x_1 => x ++ x_1) (List.reverse l))
        (Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          (l', think s))
⊢ Computation.map (fun x => List.reverse l ++ x)
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (l', s)) =
    Computation.map (fun x => List.reverse l ++ x)
      (Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        (l', s))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ Computation.destruct (toList (cons a s)) = Sum.inr (List.cons a <$> toList s)
[PROOFSTEP]
unfold toList
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ Computation.destruct
      (Computation.corec
        (fun x =>
          match x with
          | (l, s) =>
            match Seq.destruct s with
            | none => Sum.inl (List.reverse l)
            | some (none, s') => Sum.inr (l, s')
            | some (some a, s') => Sum.inr (a :: l, s'))
        ([], cons a s)) =
    Sum.inr
      (List.cons a <$>
        Computation.corec
          (fun x =>
            match x with
            | (l, s) =>
              match Seq.destruct s with
              | none => Sum.inl (List.reverse l)
              | some (none, s') => Sum.inr (l, s')
              | some (some a, s') => Sum.inr (a :: l, s'))
          ([], s))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ Computation.corec
      (fun x =>
        match Seq.destruct x.snd with
        | none => Sum.inl (List.reverse x.fst)
        | some (none, s') => Sum.inr (x.fst, s')
        | some (some a, s') => Sum.inr (a :: x.fst, s'))
      ([a], s) =
    List.cons a <$>
      Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        ([], s)
[PROOFSTEP]
rw [toList'_map]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ (fun x x_1 => x ++ x_1) (List.reverse [a]) <$> toList s =
    List.cons a <$>
      Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        ([], s)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : WSeq α
⊢ (fun x => a :: x) <$> toList s =
    List.cons a <$>
      Computation.corec
        (fun x =>
          match Seq.destruct x.snd with
          | none => Sum.inl (List.reverse x.fst)
          | some (none, s') => Sum.inr (x.fst, s')
          | some (some a, s') => Sum.inr (a :: x.fst, s'))
        ([], s)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
⊢ l ∈ toList ↑l
[PROOFSTEP]
induction' l with a l IH
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
⊢ [] ∈ toList ↑[]
[PROOFSTEP]
simp [ret_mem]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
a : α
l : List α
IH : l ∈ toList ↑l
⊢ a :: l ∈ toList ↑(a :: l)
[PROOFSTEP]
simp [ret_mem]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
a : α
l : List α
IH : l ∈ toList ↑l
⊢ a :: l ∈ Computation.think (List.cons a <$> toList ↑l)
[PROOFSTEP]
exact think_mem (Computation.mem_map _ IH)
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Computation.destruct (destruct ↑s) = Sum.inl (Option.map (fun a => (a, ↑(Seq.tail s))) (Seq.head s))
[PROOFSTEP]
simp only [destruct, Seq.destruct, Option.map_eq_map, ofSeq, Computation.corec_eq, rmap, Seq.head]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ (match
      match Option.map (fun a' => (a', Seq.tail (some <$> s))) (Seq.get? (some <$> s) 0) with
      | none => Sum.inl none
      | some (none, s') => Sum.inr s'
      | some (some a, s') => Sum.inl (some (a, s')) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (Computation.corec
          (fun s =>
            match Option.map (fun a' => (a', Seq.tail s)) (Seq.get? s 0) with
            | none => Sum.inl none
            | some (none, s') => Sum.inr s'
            | some (some a, s') => Sum.inl (some (a, s')))
          b)) =
    Sum.inl (Option.map (fun a => (a, some <$> Seq.tail s)) (Seq.get? s 0))
[PROOFSTEP]
rw [show Seq.get? (some <$> s) 0 = some <$> Seq.get? s 0 by apply Seq.map_get?]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Seq.get? (some <$> s) 0 = some <$> Seq.get? s 0
[PROOFSTEP]
apply Seq.map_get?
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ (match
      match Option.map (fun a' => (a', Seq.tail (some <$> s))) (some <$> Seq.get? s 0) with
      | none => Sum.inl none
      | some (none, s') => Sum.inr s'
      | some (some a, s') => Sum.inl (some (a, s')) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (Computation.corec
          (fun s =>
            match Option.map (fun a' => (a', Seq.tail s)) (Seq.get? s 0) with
            | none => Sum.inl none
            | some (none, s') => Sum.inr s'
            | some (some a, s') => Sum.inl (some (a, s')))
          b)) =
    Sum.inl (Option.map (fun a => (a, some <$> Seq.tail s)) (Seq.get? s 0))
[PROOFSTEP]
cases' Seq.get? s 0 with a
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ (match
      match Option.map (fun a' => (a', Seq.tail (some <$> s))) (some <$> none) with
      | none => Sum.inl none
      | some (none, s') => Sum.inr s'
      | some (some a, s') => Sum.inl (some (a, s')) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (Computation.corec
          (fun s =>
            match Option.map (fun a' => (a', Seq.tail s)) (Seq.get? s 0) with
            | none => Sum.inl none
            | some (none, s') => Sum.inr s'
            | some (some a, s') => Sum.inl (some (a, s')))
          b)) =
    Sum.inl (Option.map (fun a => (a, some <$> Seq.tail s)) none)
[PROOFSTEP]
rfl
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
⊢ (match
      match Option.map (fun a' => (a', Seq.tail (some <$> s))) (some <$> some a) with
      | none => Sum.inl none
      | some (none, s') => Sum.inr s'
      | some (some a, s') => Sum.inl (some (a, s')) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (Computation.corec
          (fun s =>
            match Option.map (fun a' => (a', Seq.tail s)) (Seq.get? s 0) with
            | none => Sum.inl none
            | some (none, s') => Sum.inr s'
            | some (some a, s') => Sum.inl (some (a, s')))
          b)) =
    Sum.inl (Option.map (fun a => (a, some <$> Seq.tail s)) (some a))
[PROOFSTEP]
dsimp only [(· <$> ·)]
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
⊢ (match
      match Option.map (fun a' => (a', Seq.tail (Seq.map some s))) (Option.map some (some a)) with
      | none => Sum.inl none
      | some (none, s') => Sum.inr s'
      | some (some a, s') => Sum.inl (some (a, s')) with
    | Sum.inl a => Sum.inl a
    | Sum.inr b =>
      Sum.inr
        (Computation.corec
          (fun s =>
            match Option.map (fun a' => (a', Seq.tail s)) (Seq.get? s 0) with
            | none => Sum.inl none
            | some (none, s') => Sum.inr s'
            | some (some a, s') => Sum.inl (some (a, s')))
          b)) =
    Sum.inl (Option.map (fun a => (a, Seq.map some (Seq.tail s))) (some a))
[PROOFSTEP]
simp [destruct]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ head ↑s = Computation.pure (Seq.head s)
[PROOFSTEP]
simp [head]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Computation.pure (Option.map (Prod.fst ∘ fun a => (a, ↑(Seq.tail s))) (Seq.head s)) = Computation.pure (Seq.head s)
[PROOFSTEP]
cases Seq.head s
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Computation.pure (Option.map (Prod.fst ∘ fun a => (a, ↑(Seq.tail s))) none) = Computation.pure none
[PROOFSTEP]
rfl
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
val✝ : α
⊢ Computation.pure (Option.map (Prod.fst ∘ fun a => (a, ↑(Seq.tail s))) (some val✝)) = Computation.pure (some val✝)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ tail ↑s = ↑(Seq.tail s)
[PROOFSTEP]
simp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Option.rec nil Prod.snd (Option.map (fun a => (a, ↑(Seq.tail s))) (Seq.head s)) = ↑(Seq.tail s)
[PROOFSTEP]
induction' s using Seq.recOn with x s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
⊢ Option.rec nil Prod.snd (Option.map (fun a => (a, ↑(Seq.tail Seq.nil))) (Seq.head Seq.nil)) = ↑(Seq.tail Seq.nil)
[PROOFSTEP]
simp [ofSeq]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
x : α
s : Seq α
⊢ Option.rec nil Prod.snd (Option.map (fun a => (a, ↑(Seq.tail (Seq.cons x s)))) (Seq.head (Seq.cons x s))) =
    ↑(Seq.tail (Seq.cons x s))
[PROOFSTEP]
simp [ofSeq]
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
⊢ nil = some <$> Seq.nil
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop (↑s) (n + 1) = ↑(Seq.drop s (n + 1))
[PROOFSTEP]
simp only [drop, Nat.add_eq, add_zero, Seq.drop]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ tail (drop (↑s) n) = ↑(Seq.tail (Seq.drop s n))
[PROOFSTEP]
rw [dropn_ofSeq s n, tail_ofSeq]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ get? (↑s) n = Computation.pure (Seq.get? s n)
[PROOFSTEP]
dsimp [get?]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ head (drop (↑s) n) = Computation.pure (Seq.get? s n)
[PROOFSTEP]
rw [dropn_ofSeq, head_ofSeq, Seq.head_dropn]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ Terminates (get? (↑s) n)
[PROOFSTEP]
rw [get?_ofSeq]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ Terminates (Computation.pure (Seq.get? s n))
[PROOFSTEP]
infer_instance
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ toSeq ↑s = s
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ↑(toSeq ↑s) = ↑s
[PROOFSTEP]
funext n
[GOAL]
case a.h
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ ↑(toSeq ↑s) n = ↑s n
[PROOFSTEP]
dsimp [toSeq]
[GOAL]
case a.h
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ Computation.get (get? (↑s) n) = ↑s n
[PROOFSTEP]
apply get_eq_of_mem
[GOAL]
case a.h.a
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ ↑s n ∈ get? (↑s) n
[PROOFSTEP]
rw [get?_ofSeq]
[GOAL]
case a.h.a
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ ↑s n ∈ Computation.pure (Seq.get? s n)
[PROOFSTEP]
apply ret_mem
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ map id s = s
[PROOFSTEP]
simp [map]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
⊢ map f (ret a) = ret (f a)
[PROOFSTEP]
simp [ret]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
⊢ map (g ∘ f) s = map g (map f s)
[PROOFSTEP]
dsimp [map]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
⊢ Seq.map (Option.map (g ∘ f)) s = Seq.map (Option.map g) (Seq.map (Option.map f) s)
[PROOFSTEP]
rw [← Seq.map_comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
⊢ Seq.map (Option.map (g ∘ f)) s = Seq.map (Option.map g ∘ Option.map f) s
[PROOFSTEP]
apply congr_fun
[GOAL]
case h
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
⊢ Seq.map (Option.map (g ∘ f)) = fun s => Seq.map (Option.map g ∘ Option.map f) s
[PROOFSTEP]
apply congr_arg
[GOAL]
case h.h
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
⊢ Option.map (g ∘ f) = Option.map g ∘ Option.map f
[PROOFSTEP]
ext ⟨⟩
[GOAL]
case h.h.h.none.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) none ↔ a✝ ∈ (Option.map g ∘ Option.map f) none
[PROOFSTEP]
rfl
[GOAL]
case h.h.h.some.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : WSeq α
val✝ : α
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) (some val✝) ↔ a✝ ∈ (Option.map g ∘ Option.map f) (some val✝)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ {S : WSeq (WSeq α)}, a ∈ join S → ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
suffices ∀ ss : WSeq α, a ∈ ss → ∀ s S, append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s from
  fun S h => (this _ h nil S (by simp) (by simp [h])).resolve_left (not_mem_nil _)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
this :
  ∀ (ss : WSeq α),
    a ∈ ss →
      ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
h : a ∈ join S
⊢ append nil (join S) = join S
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
this :
  ∀ (ss : WSeq α),
    a ∈ ss →
      ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
h : a ∈ join S
⊢ a ∈ append nil (join S)
[PROOFSTEP]
simp [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
⊢ ∀ (ss : WSeq α),
    a ∈ ss →
      ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ss h
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
⊢ ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
apply mem_rec_on h <;> [intro b ss o; intro ss IH]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
⊢ ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
apply mem_rec_on h
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
⊢ ∀ (b : α) (s' : WSeq α),
    (a = b ∨
        ∀ (s : WSeq α) (S : WSeq (WSeq α)),
          append s (join S) = s' → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s) →
      ∀ (s : WSeq α) (S : WSeq (WSeq α)),
        append s (join S) = cons b s' → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro b ss o
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
⊢ ∀ (s : WSeq α),
    (∀ (s_1 : WSeq α) (S : WSeq (WSeq α)),
        append s_1 (join S) = s → a ∈ append s_1 (join S) → a ∈ s_1 ∨ ∃ s, s ∈ S ∧ a ∈ s) →
      ∀ (s_1 : WSeq α) (S : WSeq (WSeq α)),
        append s_1 (join S) = think s → a ∈ append s_1 (join S) → a ∈ s_1 ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ss IH
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
⊢ ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = cons b ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro s S
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
⊢ ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = think ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro s S
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append s (join S) = cons b ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with b' s s <;> [induction' S using WSeq.recOn with s S S; skip; skip]
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append s (join S) = cons b ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with b' s s
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
⊢ append nil (join S) = cons b ss → a ∈ append nil (join S) → a ∈ nil ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
⊢ append (cons b' s) (join S) = cons b ss → a ∈ append (cons b' s) (join S) → a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
skip
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
⊢ append (think s) (join S) = cons b ss → a ∈ append (think s) (join S) → a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
skip
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
⊢ append nil (join nil) = cons b ss → a ∈ append nil (join nil) → a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append nil (join (cons s S)) = cons b ss →
    a ∈ append nil (join (cons s S)) → a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
intro ej m
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
⊢ append nil (join (think S)) = cons b ss → a ∈ append nil (join (think S)) → a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
⊢ append (cons b' s) (join S) = cons b ss → a ∈ append (cons b' s) (join S) → a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
⊢ append (think s) (join S) = cons b ss → a ∈ append (think s) (join S) → a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
ej : append nil (join nil) = cons b ss
m : a ∈ append nil (join nil)
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
ej : append nil (join (cons s S)) = cons b ss
m : a ∈ append nil (join (cons s S))
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
simp at ej 
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
ej : append nil (join (think S)) = cons b ss
m : a ∈ append nil (join (think S))
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
ej : append (cons b' s) (join S) = cons b ss
m : a ∈ append (cons b' s) (join S)
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
ej : append (think s) (join S) = cons b ss
m : a ∈ append (think s) (join S)
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
m : a ∈ append nil (join nil)
ej : nil = cons b ss
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = cons b ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = cons b ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = cons b ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
m : a ∈ append nil (join nil)
ej : nil = cons b ss
this : Seq.destruct nil = Seq.destruct (cons b ss)
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = cons b ss
this : Seq.destruct (think (append s (join S))) = Seq.destruct (cons b ss)
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = cons b ss
this : Seq.destruct (think (join S)) = Seq.destruct (cons b ss)
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
this : Seq.destruct (cons b' (append s (join S))) = Seq.destruct (cons b ss)
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = cons b ss
this : Seq.destruct (think (append s (join S))) = Seq.destruct (cons b ss)
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
this : b' = b ∧ append s (join S) = ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
try cases this; try contradiction
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
this : b' = b ∧ append s (join S) = ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
cases this
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
left✝ : b' = b
right✝ : append s (join S) = ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
try contradiction
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
left✝ : b' = b
right✝ : append s (join S) = ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
contradiction
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
b : α
ss : WSeq α
o :
  a = b ∨
    ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = cons b ss
left✝ : b' = b
right✝ : append s (join S) = ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
substs b' ss
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (cons b s) (join S)
o :
  a = b ∨
    ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
      append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : cons b (append s (join S)) = cons b (append s (join S))
⊢ a ∈ cons b s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at m ⊢
[GOAL]
case h1.h2.intro
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
o :
  a = b ∨
    ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
      append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : cons b (append s (join S)) = cons b (append s (join S))
m : a = b ∨ a ∈ append s (join S)
⊢ (a = b ∨ a ∈ s) ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
cases' o with e IH
[GOAL]
case h1.h2.intro.inl
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
ej : cons b (append s (join S)) = cons b (append s (join S))
m : a = b ∨ a ∈ append s (join S)
e : a = b
⊢ (a = b ∨ a ∈ s) ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp [e]
[GOAL]
case h1.h2.intro.inr
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
ej : cons b (append s (join S)) = cons b (append s (join S))
m : a = b ∨ a ∈ append s (join S)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
⊢ (a = b ∨ a ∈ s) ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
cases' m with e m
[GOAL]
case h1.h2.intro.inr.inl
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
ej : cons b (append s (join S)) = cons b (append s (join S))
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
e : a = b
⊢ (a = b ∨ a ∈ s) ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp [e]
[GOAL]
case h1.h2.intro.inr.inr
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
b : α
S : WSeq (WSeq α)
s : WSeq α
ej : cons b (append s (join S)) = cons b (append s (join S))
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
m : a ∈ append s (join S)
⊢ (a = b ∨ a ∈ s) ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
exact Or.imp_left Or.inr (IH _ _ rfl m)
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append s (join S) = think ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with b' s s <;> [induction' S using WSeq.recOn with s S S; skip; skip]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append s (join S) = think ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' s using WSeq.recOn with b' s s
[GOAL]
case h2.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
⊢ append nil (join S) = think ss → a ∈ append nil (join S) → a ∈ nil ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
⊢ append (cons b' s) (join S) = think ss → a ∈ append (cons b' s) (join S) → a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
skip
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
⊢ append (think s) (join S) = think ss → a ∈ append (think s) (join S) → a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
skip
[GOAL]
case h2.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
⊢ append nil (join nil) = think ss → a ∈ append nil (join nil) → a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
⊢ append nil (join (cons s S)) = think ss → a ∈ append nil (join (cons s S)) → a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
intro ej m
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
⊢ append nil (join (think S)) = think ss → a ∈ append nil (join (think S)) → a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
⊢ append (cons b' s) (join S) = think ss → a ∈ append (cons b' s) (join S) → a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
⊢ append (think s) (join S) = think ss → a ∈ append (think s) (join S) → a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
intro ej m
[GOAL]
case h2.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
ej : append nil (join nil) = think ss
m : a ∈ append nil (join nil)
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
ej : append nil (join (cons s S)) = think ss
m : a ∈ append nil (join (cons s S))
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
simp at ej 
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
ej : append nil (join (think S)) = think ss
m : a ∈ append nil (join (think S))
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
ej : append (cons b' s) (join S) = think ss
m : a ∈ append (cons b' s) (join S)
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
ej : append (think s) (join S) = think ss
m : a ∈ append (think s) (join S)
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at ej 
[GOAL]
case h2.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
m : a ∈ append nil (join nil)
ej : nil = think ss
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = think ss
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
have := congr_arg Seq.destruct ej
[GOAL]
case h2.h1.h1
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
m : a ∈ append nil (join nil)
ej : nil = think ss
this : Seq.destruct nil = Seq.destruct (think ss)
⊢ a ∈ nil ∨ ∃ s, s ∈ nil ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : Seq.destruct (think (append s (join S))) = Seq.destruct (think ss)
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : Seq.destruct (think (join S)) = Seq.destruct (think ss)
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
b' : α
s : WSeq α
m : a ∈ append (cons b' s) (join S)
ej : cons b' (append s (join S)) = think ss
this : Seq.destruct (cons b' (append s (join S))) = Seq.destruct (think ss)
⊢ a ∈ cons b' s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : Seq.destruct (think (append s (join S))) = Seq.destruct (think ss)
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at this 
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
try
  {try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
{try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
try {have := this.1
}
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
{have := this.1
}
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
have := this.1
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
contradiction
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
try
  {try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
{try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
try {have := this.1
}
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
{have := this.1
}
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
have := this.1
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
contradiction
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
try
  {try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
{try {have := this.1
  };
  contradiction
}
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
try {have := this.1
}
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
{have := this.1
}
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
have := this.1
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
contradiction
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
subst ss
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
ej : think (join S) = think ss
this : join S = ss
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
subst ss
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss✝ : WSeq α
h : a ∈ ss✝
ss : WSeq α
IH : ∀ (s : WSeq α) (S : WSeq (WSeq α)), append s (join S) = ss → a ∈ append s (join S) → a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
ej : think (append s (join S)) = think ss
this : append s (join S) = ss
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
subst ss
[GOAL]
case h2.h1.h2
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
⊢ a ∈ nil ∨ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
apply Or.inr
[GOAL]
case h2.h1.h2.h
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
m : a ∈ append nil (join (cons s S))
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
⊢ ∃ s_1, s_1 ∈ cons s S ∧ a ∈ s_1
[PROOFSTEP]
simp [-exists_eq_or_imp] at m ⊢
[GOAL]
case h2.h1.h2.h
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
m : a ∈ append s (join S)
⊢ ∃ s_1, (s_1 = s ∨ s_1 ∈ S) ∧ a ∈ s_1
[PROOFSTEP]
cases' IH s S rfl m with as ex
[GOAL]
case h2.h1.h2.h.inl
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
m : a ∈ append s (join S)
as : a ∈ s
⊢ ∃ s_1, (s_1 = s ∨ s_1 ∈ S) ∧ a ∈ s_1
[PROOFSTEP]
exact ⟨s, Or.inl rfl, as⟩
[GOAL]
case h2.h1.h2.h.inr
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
m : a ∈ append s (join S)
ex : ∃ s, s ∈ S ∧ a ∈ s
⊢ ∃ s_1, (s_1 = s ∨ s_1 ∈ S) ∧ a ∈ s_1
[PROOFSTEP]
rcases ex with ⟨s', sS, as⟩
[GOAL]
case h2.h1.h2.h.inr.intro.intro
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
s : WSeq α
S : WSeq (WSeq α)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
m : a ∈ append s (join S)
s' : WSeq α
sS : s' ∈ S
as : a ∈ s'
⊢ ∃ s_1, (s_1 = s ∨ s_1 ∈ S) ∧ a ∈ s_1
[PROOFSTEP]
exact ⟨s', Or.inr sS, as⟩
[GOAL]
case h2.h1.h3
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
⊢ a ∈ nil ∨ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
apply Or.inr
[GOAL]
case h2.h1.h3.h
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
m : a ∈ append nil (join (think S))
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
⊢ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
simp at m 
[GOAL]
case h2.h1.h3.h
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
m : a ∈ join S
⊢ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
rcases(IH nil S (by simp) (by simp [m])).resolve_left (not_mem_nil _) with ⟨s, sS, as⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
m : a ∈ join S
⊢ append nil (join S) = join S
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
m : a ∈ join S
⊢ a ∈ append nil (join S)
[PROOFSTEP]
simp [m]
[GOAL]
case h2.h1.h3.h.intro.intro
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
m : a ∈ join S
s : WSeq α
sS : s ∈ S
as : a ∈ s
⊢ ∃ s, s ∈ think S ∧ a ∈ s
[PROOFSTEP]
exact ⟨s, by simp [sS], as⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
IH :
  ∀ (s : WSeq α) (S_1 : WSeq (WSeq α)),
    append s (join S_1) = join S → a ∈ append s (join S_1) → a ∈ s ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (join S) = think (join S)
m : a ∈ join S
s : WSeq α
sS : s ∈ S
as : a ∈ s
⊢ s ∈ think S
[PROOFSTEP]
simp [sS]
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
s : WSeq α
m : a ∈ append (think s) (join S)
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
⊢ a ∈ think s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
simp at m IH ⊢
[GOAL]
case h2.h3
α : Type u
β : Type v
γ : Type w
a : α
ss : WSeq α
h : a ∈ ss
S : WSeq (WSeq α)
s : WSeq α
IH :
  ∀ (s_1 : WSeq α) (S_1 : WSeq (WSeq α)),
    append s_1 (join S_1) = append s (join S) → a ∈ append s_1 (join S_1) → a ∈ s_1 ∨ ∃ s, s ∈ S_1 ∧ a ∈ s
ej : think (append s (join S)) = think (append s (join S))
m : a ∈ append s (join S)
⊢ a ∈ s ∨ ∃ s, s ∈ S ∧ a ∈ s
[PROOFSTEP]
apply IH _ _ rfl m
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
f : α → WSeq β
b : β
h : b ∈ bind s f
t : WSeq β
tm : t ∈ map f s
bt : b ∈ t
a : α
as : a ∈ s
e : f a = t
⊢ b ∈ f a
[PROOFSTEP]
rwa [e]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ destruct (map f s) = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
[PROOFSTEP]
apply
  Computation.eq_of_bisim fun c1 c2 =>
    ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ Computation.IsBisimulation fun c1 c2 =>
    ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
[PROOFSTEP]
intro c1 c2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
h : ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
cases' h with s h
[GOAL]
case bisim.intro
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s : WSeq α
h : c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
rw [h.left, h.right]
[GOAL]
case bisim.intro
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s : WSeq α
h : c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct (destruct (map f s)))
    (Computation.destruct (Computation.map (Option.map (Prod.map f (map f))) (destruct s)))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case bisim.intro.h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s : WSeq α
h✝ : c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s)
h : c1 = destruct (map f nil) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct nil)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct (destruct (map f nil)))
    (Computation.destruct (Computation.map (Option.map (Prod.map f (map f))) (destruct nil)))
[PROOFSTEP]
simp
[GOAL]
case bisim.intro.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝¹ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s✝ : WSeq α
h✝ : c1 = destruct (map f s✝) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s✝)
a : α
s : WSeq α
h : c1 = destruct (map f (cons a s)) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct (cons a s))
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct (destruct (map f (cons a s))))
    (Computation.destruct (Computation.map (Option.map (Prod.map f (map f))) (destruct (cons a s))))
[PROOFSTEP]
simp
[GOAL]
case bisim.intro.h3
α : Type u
β : Type v
γ : Type w
f : α → β
s✝¹ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s✝ : WSeq α
h✝ : c1 = destruct (map f s✝) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s✝)
s : WSeq α
h : c1 = destruct (map f (think s)) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct (think s))
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s, c1 = destruct (map f s) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s))
    (Computation.destruct (destruct (map f (think s))))
    (Computation.destruct (Computation.map (Option.map (Prod.map f (map f))) (destruct (think s))))
[PROOFSTEP]
simp
[GOAL]
case bisim.intro.h3
α : Type u
β : Type v
γ : Type w
f : α → β
s✝¹ : WSeq α
c1 c2 : Computation (Option (β × WSeq β))
s✝ : WSeq α
h✝ : c1 = destruct (map f s✝) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct s✝)
s : WSeq α
h : c1 = destruct (map f (think s)) ∧ c2 = Computation.map (Option.map (Prod.map f (map f))) (destruct (think s))
⊢ ∃ s_1,
    destruct (map f s) = destruct (map f s_1) ∧
      Computation.map (Option.map (Prod.map f (map f))) (destruct s) =
        Computation.map (Option.map (Prod.map f (map f))) (destruct s_1)
[PROOFSTEP]
exact ⟨s, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ ∃ s_1,
    destruct (map f s) = destruct (map f s_1) ∧
      Computation.map (Option.map (Prod.map f (map f))) (destruct s) =
        Computation.map (Option.map (Prod.map f (map f))) (destruct s_1)
[PROOFSTEP]
exact ⟨s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ Computation.LiftRel (LiftRelO S fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t)
    (destruct (map f1 s)) (destruct (map f2 t))
[PROOFSTEP]
simp [destruct_map]
[GOAL]
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
      | x, x_2 => False)
    (Computation.map (Option.map (Prod.map f1 (map f1))) (destruct s))
    (Computation.map (Option.map (Prod.map f2 (map f2))) (destruct t))
[PROOFSTEP]
apply Computation.liftRel_map _ _ (liftRel_destruct h)
[GOAL]
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      match Option.map (Prod.map f1 (map f1)) a, Option.map (Prod.map f2 (map f2)) b with
      | none, none => True
      | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
      | x, x_1 => False
[PROOFSTEP]
intro o p h
[GOAL]
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
⊢ match Option.map (Prod.map f1 (map f1)) o, Option.map (Prod.map f2 (map f2)) p with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
cases' o with a
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) none p
⊢ match Option.map (Prod.map f1 (map f1)) none, Option.map (Prod.map f2 (map f2)) p with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
cases' p with b
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
p : Option (β × WSeq β)
a : α × WSeq α
h : LiftRelO R (LiftRel R) (some a) p
⊢ match Option.map (Prod.map f1 (map f1)) (some a), Option.map (Prod.map f2 (map f2)) p with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
cases' p with b
[GOAL]
case none.none
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
h : LiftRelO R (LiftRel R) none none
⊢ match Option.map (Prod.map f1 (map f1)) none, Option.map (Prod.map f2 (map f2)) none with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case none.some
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
b : β × WSeq β
h : LiftRelO R (LiftRel R) none (some b)
⊢ match Option.map (Prod.map f1 (map f1)) none, Option.map (Prod.map f2 (map f2)) (some b) with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case some.none
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
a : α × WSeq α
h : LiftRelO R (LiftRel R) (some a) none
⊢ match Option.map (Prod.map f1 (map f1)) (some a), Option.map (Prod.map f2 (map f2)) none with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case some.some
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
a : α × WSeq α
b : β × WSeq β
h : LiftRelO R (LiftRel R) (some a) (some b)
⊢ match Option.map (Prod.map f1 (map f1)) (some a), Option.map (Prod.map f2 (map f2)) (some b) with
  | none, none => True
  | some (a, s), some (b, t) => S a b ∧ ∃ s_1, s = map f1 s_1 ∧ ∃ x, t = map f2 x ∧ LiftRel R s_1 x
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case none.some
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
b : β × WSeq β
h : LiftRelO R (LiftRel R) none (some b)
⊢ False
[PROOFSTEP]
cases b
[GOAL]
case none.some.mk
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
fst✝ : β
snd✝ : WSeq β
h : LiftRelO R (LiftRel R) none (some (fst✝, snd✝))
⊢ False
[PROOFSTEP]
cases h
[GOAL]
case some.none
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
a : α × WSeq α
h : LiftRelO R (LiftRel R) (some a) none
⊢ False
[PROOFSTEP]
cases a
[GOAL]
case some.none.mk
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
fst✝ : α
snd✝ : WSeq α
h : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) none
⊢ False
[PROOFSTEP]
cases h
[GOAL]
case some.some
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s : WSeq α
t : WSeq β
h✝ : LiftRel R s t
a : α × WSeq α
b : β × WSeq β
h : LiftRelO R (LiftRel R) (some a) (some b)
⊢ S (f1 a.fst) (f2 b.fst) ∧ ∃ s, map f1 a.snd = map f1 s ∧ ∃ x, map f2 b.snd = map f2 x ∧ LiftRel R s x
[PROOFSTEP]
cases' a with a s
[GOAL]
case some.some.mk
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s✝ : WSeq α
t : WSeq β
h✝ : LiftRel R s✝ t
b : β × WSeq β
a : α
s : WSeq α
h : LiftRelO R (LiftRel R) (some (a, s)) (some b)
⊢ S (f1 (a, s).fst) (f2 b.fst) ∧ ∃ s_1, map f1 (a, s).snd = map f1 s_1 ∧ ∃ x, map f2 b.snd = map f2 x ∧ LiftRel R s_1 x
[PROOFSTEP]
cases' b with b t
[GOAL]
case some.some.mk.mk
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s✝ : WSeq α
t✝ : WSeq β
h✝ : LiftRel R s✝ t✝
a : α
s : WSeq α
b : β
t : WSeq β
h : LiftRelO R (LiftRel R) (some (a, s)) (some (b, t))
⊢ S (f1 (a, s).fst) (f2 (b, t).fst) ∧
    ∃ s_1, map f1 (a, s).snd = map f1 s_1 ∧ ∃ x, map f2 (b, t).snd = map f2 x ∧ LiftRel R s_1 x
[PROOFSTEP]
cases' h with r h
[GOAL]
case some.some.mk.mk.intro
α : Type u
β : Type v
γ : Type w
δ : Type u_1
R : α → β → Prop
S : γ → δ → Prop
s1✝ : WSeq α
s2✝ : WSeq β
f1 : α → γ
f2 : β → δ
h1 : LiftRel R s1✝ s2✝
h2 : ∀ {a : α} {b : β}, R a b → S (f1 a) (f2 b)
s1 : WSeq γ
s2 : WSeq δ
h✝¹ : (fun s1 s2 => ∃ s t, s1 = map f1 s ∧ s2 = map f2 t ∧ LiftRel R s t) s1 s2
s✝ : WSeq α
t✝ : WSeq β
h✝ : LiftRel R s✝ t✝
a : α
s : WSeq α
b : β
t : WSeq β
r : R a b
h : LiftRel R s t
⊢ S (f1 (a, s).fst) (f2 (b, t).fst) ∧
    ∃ s_1, map f1 (a, s).snd = map f1 s_1 ∧ ∃ x, map f2 (b, t).snd = map f2 x ∧ LiftRel R s_1 x
[PROOFSTEP]
exact ⟨h2 r, s, rfl, t, rfl, h⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
⊢ destruct (append s t) = Computation.bind (destruct s) (destruct_append.aux t)
[PROOFSTEP]
apply
  Computation.eq_of_bisim
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = (destruct s).bind (destruct_append.aux t)) _ ⟨s, t, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
⊢ Computation.IsBisimulation fun c1 c2 =>
    ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
[PROOFSTEP]
intro c1 c2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
s t : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
h : ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
rcases h with ⟨s, t, h⟩
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h : c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
rw [h.left, h.right]
[GOAL]
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h : c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct (destruct (append s t)))
    (Computation.destruct (Computation.bind (destruct s) (destruct_append.aux t)))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case intro.intro.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h✝ : c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
h : c1 = destruct (append nil t) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct (destruct (append nil t)))
    (Computation.destruct (Computation.bind (destruct nil) (destruct_append.aux t)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h2
α : Type u
β : Type v
γ : Type w
s✝¹ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s✝ t : WSeq α
h✝ : c1 = destruct (append s✝ t) ∧ c2 = Computation.bind (destruct s✝) (destruct_append.aux t)
a : α
s : WSeq α
h : c1 = destruct (append (cons a s) t) ∧ c2 = Computation.bind (destruct (cons a s)) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct (destruct (append (cons a s) t)))
    (Computation.destruct (Computation.bind (destruct (cons a s)) (destruct_append.aux t)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝¹ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s✝ t : WSeq α
h✝ : c1 = destruct (append s✝ t) ∧ c2 = Computation.bind (destruct s✝) (destruct_append.aux t)
s : WSeq α
h : c1 = destruct (append (think s) t) ∧ c2 = Computation.bind (destruct (think s)) (destruct_append.aux t)
⊢ Computation.BisimO
    (fun c1 c2 => ∃ s t, c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t))
    (Computation.destruct (destruct (append (think s) t)))
    (Computation.destruct (Computation.bind (destruct (think s)) (destruct_append.aux t)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h✝ : c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
h : c1 = destruct (append nil t) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t)
⊢ match Computation.destruct (destruct t), Computation.destruct (destruct t) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    ∃ s_1 t,
      s = destruct (append s_1 t) ∧
        s' =
          Computation.bind (destruct s_1) fun x =>
            match x with
            | none => destruct t
            | some (a, s) => Computation.pure (some (a, append s t))
  | x, x_1 => False
[PROOFSTEP]
induction' t using WSeq.recOn with b t t
[GOAL]
case intro.intro.h1.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t : WSeq α
h✝² : c1 = destruct (append s t) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t)
h✝¹ : c1 = destruct (append nil t) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t)
h✝ : c1 = destruct (append s nil) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux nil)
h : c1 = destruct (append nil nil) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux nil)
⊢ match Computation.destruct (destruct nil), Computation.destruct (destruct nil) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    ∃ s_1 t,
      s = destruct (append s_1 t) ∧
        s' =
          Computation.bind (destruct s_1) fun x =>
            match x with
            | none => destruct t
            | some (a, s) => Computation.pure (some (a, append s t))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t✝ : WSeq α
h✝² : c1 = destruct (append s t✝) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t✝)
h✝¹ : c1 = destruct (append nil t✝) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t✝)
b : α
t : WSeq α
h✝ : c1 = destruct (append s (cons b t)) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux (cons b t))
h : c1 = destruct (append nil (cons b t)) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux (cons b t))
⊢ match Computation.destruct (destruct (cons b t)), Computation.destruct (destruct (cons b t)) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    ∃ s_1 t,
      s = destruct (append s_1 t) ∧
        s' =
          Computation.bind (destruct s_1) fun x =>
            match x with
            | none => destruct t
            | some (a, s) => Computation.pure (some (a, append s t))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t✝ : WSeq α
h✝² : c1 = destruct (append s t✝) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t✝)
h✝¹ : c1 = destruct (append nil t✝) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t✝)
t : WSeq α
h✝ : c1 = destruct (append s (think t)) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux (think t))
h : c1 = destruct (append nil (think t)) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux (think t))
⊢ match Computation.destruct (destruct (think t)), Computation.destruct (destruct (think t)) with
  | Sum.inl a, Sum.inl a' => a = a'
  | Sum.inr s, Sum.inr s' =>
    ∃ s_1 t,
      s = destruct (append s_1 t) ∧
        s' =
          Computation.bind (destruct s_1) fun x =>
            match x with
            | none => destruct t
            | some (a, s) => Computation.pure (some (a, append s t))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t✝ : WSeq α
h✝² : c1 = destruct (append s t✝) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t✝)
h✝¹ : c1 = destruct (append nil t✝) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t✝)
t : WSeq α
h✝ : c1 = destruct (append s (think t)) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux (think t))
h : c1 = destruct (append nil (think t)) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux (think t))
⊢ ∃ s t_1,
    destruct t = destruct (append s t_1) ∧
      destruct t =
        Computation.bind (destruct s) fun x =>
          match x with
          | none => destruct t_1
          | some (a, s) => Computation.pure (some (a, append s t_1))
[PROOFSTEP]
refine' ⟨nil, t, _, _⟩
[GOAL]
case intro.intro.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t✝ : WSeq α
h✝² : c1 = destruct (append s t✝) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t✝)
h✝¹ : c1 = destruct (append nil t✝) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t✝)
t : WSeq α
h✝ : c1 = destruct (append s (think t)) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux (think t))
h : c1 = destruct (append nil (think t)) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux (think t))
⊢ destruct t = destruct (append nil t)
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s t✝ : WSeq α
h✝² : c1 = destruct (append s t✝) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux t✝)
h✝¹ : c1 = destruct (append nil t✝) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux t✝)
t : WSeq α
h✝ : c1 = destruct (append s (think t)) ∧ c2 = Computation.bind (destruct s) (destruct_append.aux (think t))
h : c1 = destruct (append nil (think t)) ∧ c2 = Computation.bind (destruct nil) (destruct_append.aux (think t))
⊢ destruct t =
    Computation.bind (destruct nil) fun x =>
      match x with
      | none => destruct t
      | some (a, s) => Computation.pure (some (a, append s t))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.h3
α : Type u
β : Type v
γ : Type w
s✝¹ t✝ : WSeq α
c1 c2 : Computation (Option (α × WSeq α))
s✝ t : WSeq α
h✝ : c1 = destruct (append s✝ t) ∧ c2 = Computation.bind (destruct s✝) (destruct_append.aux t)
s : WSeq α
h : c1 = destruct (append (think s) t) ∧ c2 = Computation.bind (destruct (think s)) (destruct_append.aux t)
⊢ ∃ s_1 t_1,
    destruct (append s t) = destruct (append s_1 t_1) ∧
      (Computation.bind (destruct s) fun x =>
          match x with
          | none => destruct t
          | some (a, s) => Computation.pure (some (a, append s t))) =
        Computation.bind (destruct s_1) fun x =>
          match x with
          | none => destruct t_1
          | some (a, s) => Computation.pure (some (a, append s t_1))
[PROOFSTEP]
exact ⟨s, t, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
⊢ destruct (join S) = Computation.bind (destruct S) destruct_join.aux
[PROOFSTEP]
apply
  Computation.eq_of_bisim
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = (destruct S).bind destruct_join.aux) _
    (Or.inr ⟨S, rfl, rfl⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
⊢ Computation.IsBisimulation fun c1 c2 =>
    c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
[PROOFSTEP]
intro c1 c2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
exact
  match c1, c2, h with
  | c, _, Or.inl <| rfl => by cases c.destruct <;> simp
  | _, _, Or.inr ⟨S, rfl, rfl⟩ => by
    induction' S using WSeq.recOn with s S S <;> simp
    · refine' Or.inr ⟨S, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
c : Computation (Option (α × WSeq α))
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct c) (Computation.destruct c)
[PROOFSTEP]
cases c.destruct
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
c : Computation (Option (α × WSeq α))
val✝ : Option (α × WSeq α)
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Sum.inl val✝) (Sum.inl val✝)
[PROOFSTEP]
simp
[GOAL]
case inr
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
c val✝ : Computation (Option (α × WSeq α))
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Sum.inr val✝) (Sum.inr val✝)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
S✝ : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
S : WSeq (WSeq α)
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct (destruct (join S))) (Computation.destruct (Computation.bind (destruct S) destruct_join.aux))
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
S : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct (destruct (join nil)))
    (Computation.destruct (Computation.bind (destruct nil) destruct_join.aux))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
S✝ : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
s : WSeq α
S : WSeq (WSeq α)
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct (destruct (join (cons s S))))
    (Computation.destruct (Computation.bind (destruct (cons s S)) destruct_join.aux))
[PROOFSTEP]
simp
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
S✝ : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
S : WSeq (WSeq α)
⊢ Computation.BisimO
    (fun c1 c2 => c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux)
    (Computation.destruct (destruct (join (think S))))
    (Computation.destruct (Computation.bind (destruct (think S)) destruct_join.aux))
[PROOFSTEP]
simp
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
S✝ : WSeq (WSeq α)
c1 c2 : Computation (Option (α × WSeq α))
h : c1 = c2 ∨ ∃ S, c1 = destruct (join S) ∧ c2 = Computation.bind (destruct S) destruct_join.aux
S : WSeq (WSeq α)
⊢ (destruct (join S) =
      Computation.bind (destruct S) fun x =>
        match x with
        | none => Computation.pure none
        | some (s, S) => Computation.think (destruct (append s (join S)))) ∨
    ∃ S_1,
      destruct (join S) = destruct (join S_1) ∧
        (Computation.bind (destruct S) fun x =>
            match x with
            | none => Computation.pure none
            | some (s, S) => Computation.think (destruct (append s (join S)))) =
          Computation.bind (destruct S_1) fun x =>
            match x with
            | none => Computation.pure none
            | some (s, S) => Computation.think (destruct (append s (join S)))
[PROOFSTEP]
refine' Or.inr ⟨S, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 s2 : WSeq α
t1 t2 : WSeq β
h1 : LiftRel R s1 t1
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ Computation.LiftRel
    (LiftRelO R fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) (destruct s)
    (destruct t)
[PROOFSTEP]
apply Computation.LiftRel.imp _ _ _ (liftRel_destruct h)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 s2 : WSeq α
t1 t2 : WSeq β
h1 : LiftRel R s1 t1
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s : WSeq α
t : WSeq β
h : LiftRel R s t
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      LiftRelO R (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) a b
[PROOFSTEP]
intro a b
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 s2 : WSeq α
t1 t2 : WSeq β
h1 : LiftRel R s1 t1
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s : WSeq α
t : WSeq β
h : LiftRel R s t
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ LiftRelO R (LiftRel R) a b →
    LiftRelO R (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) a b
[PROOFSTEP]
apply LiftRelO.imp_right
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 s2 : WSeq α
t1 t2 : WSeq β
h1 : LiftRel R s1 t1
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s : WSeq α
t : WSeq β
h : LiftRel R s t
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ ∀ (s : WSeq α) (t : WSeq β),
    LiftRel R s t → LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1
[PROOFSTEP]
intro s t
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1 s2 : WSeq α
t1 t2 : WSeq β
h1 : LiftRel R s1 t1
h2 : LiftRel R s2 t2
s✝¹ : WSeq α
t✝¹ : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝¹ t✝¹
s✝ : WSeq α
t✝ : WSeq β
h : LiftRel R s✝ t✝
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
⊢ LiftRel R s t → LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1
[PROOFSTEP]
apply Or.inl
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h : LiftRel R s1 t1
⊢ Computation.LiftRel
    (LiftRelO R fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1)
    (destruct (append s1 s2)) (destruct (append t1 t2))
[PROOFSTEP]
simp [destruct_append]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h : LiftRel R s1 t1
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (Computation.bind (destruct s1) fun x =>
      match x with
      | none => destruct s2
      | some (a, s) => Computation.pure (some (a, append s s2)))
    (Computation.bind (destruct t1) fun x =>
      match x with
      | none => destruct t2
      | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
apply Computation.liftRel_bind _ _ (liftRel_destruct h)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h : LiftRel R s1 t1
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      Computation.LiftRel
        (fun x x_1 =>
          match x, x_1 with
          | none, none => True
          | some (a, s), some (b, t) =>
            R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
          | x, x_2 => False)
        (match a with
        | none => destruct s2
        | some (a, s) => Computation.pure (some (a, append s s2)))
        (match b with
        | none => destruct t2
        | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
intro o p h
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match o with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match p with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' o with a
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) none p
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match none with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match p with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' p with b
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
p : Option (β × WSeq β)
a : α × WSeq α
h : LiftRelO R (LiftRel R) (some a) p
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some a with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match p with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' p with b
[GOAL]
case none.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match none with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match none with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
simp
[GOAL]
case none.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (destruct s2) (destruct t2)
[PROOFSTEP]
apply Computation.LiftRel.imp _ _ _ (liftRel_destruct h2)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      match a, b with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_1 => False
[PROOFSTEP]
intro a b
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ LiftRelO R (LiftRel R) a b →
    match a, b with
    | none, none => True
    | some (a, s), some (b, t) =>
      R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
    | x, x_1 => False
[PROOFSTEP]
apply LiftRelO.imp_right
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
a : Option (α × WSeq α)
b : Option (β × WSeq β)
⊢ ∀ (s : WSeq α) (t : WSeq β),
    LiftRel R s t → LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x
[PROOFSTEP]
intro s t
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
h : LiftRelO R (LiftRel R) none none
a : Option (α × WSeq α)
b : Option (β × WSeq β)
s : WSeq α
t : WSeq β
⊢ LiftRel R s t → LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x
[PROOFSTEP]
apply Or.inl
[GOAL]
case none.some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
b : β × WSeq β
h : LiftRelO R (LiftRel R) none (some b)
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match none with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some b with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases b
[GOAL]
case none.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
fst✝ : β
snd✝ : WSeq β
h : LiftRelO R (LiftRel R) none (some (fst✝, snd✝))
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match none with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some (fst✝, snd✝) with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases h
[GOAL]
case some.none
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
a : α × WSeq α
h : LiftRelO R (LiftRel R) (some a) none
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some a with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match none with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases a
[GOAL]
case some.none.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
fst✝ : α
snd✝ : WSeq α
h : LiftRelO R (LiftRel R) (some (fst✝, snd✝)) none
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some (fst✝, snd✝) with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match none with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases h
[GOAL]
case some.some
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
a : α × WSeq α
b : β × WSeq β
h : LiftRelO R (LiftRel R) (some a) (some b)
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some a with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some b with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' a with a s
[GOAL]
case some.some.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s✝ : WSeq α
t : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
b : β × WSeq β
a : α
s : WSeq α
h : LiftRelO R (LiftRel R) (some (a, s)) (some b)
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some (a, s) with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some b with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' b with b t
[GOAL]
case some.some.mk.mk
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
a : α
s : WSeq α
b : β
t : WSeq β
h : LiftRelO R (LiftRel R) (some (a, s)) (some (b, t))
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some (a, s) with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some (b, t) with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
cases' h with r h
[GOAL]
case some.some.mk.mk.intro
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
a : α
s : WSeq α
b : β
t : WSeq β
r : R a b
h : LiftRel R s t
⊢ Computation.LiftRel
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        R a b ∧ (LiftRel R s t ∨ ∃ s1, s = append s1 s2 ∧ ∃ x, t = append x t2 ∧ LiftRel R s1 x)
      | x, x_2 => False)
    (match some (a, s) with
    | none => destruct s2
    | some (a, s) => Computation.pure (some (a, append s s2)))
    (match some (b, t) with
    | none => destruct t2
    | some (a, s) => Computation.pure (some (a, append s t2)))
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
case some.some.mk.mk.intro
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
s1✝ s2 : WSeq α
t1✝ t2 : WSeq β
h1 : LiftRel R s1✝ t1✝
h2 : LiftRel R s2 t2
s✝ : WSeq α
t✝ : WSeq β
h✝¹ : (fun s t => LiftRel R s t ∨ ∃ s1 t1, s = append s1 s2 ∧ t = append t1 t2 ∧ LiftRel R s1 t1) s✝ t✝
s1 : WSeq α
t1 : WSeq β
h✝ : LiftRel R s1 t1
a : α
s : WSeq α
b : β
t : WSeq β
r : R a b
h : LiftRel R s t
⊢ R a b ∧
    (LiftRel R (append s s2) (append t t2) ∨
      ∃ s1, append s s2 = append s1 s2 ∧ ∃ x, append t t2 = append x t2 ∧ LiftRel R s1 x)
[PROOFSTEP]
exact ⟨r, Or.inr ⟨s, rfl, t, rfl, h⟩⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
U : WSeq α → WSeq β → Prop
ST : LiftRel (LiftRel R) S T
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
a : Option (α × WSeq α)
ma : a ∈ destruct (join S)
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
cases' exists_results_of_mem ma with n h
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
U : WSeq α → WSeq β → Prop
ST : LiftRel (LiftRel R) S T
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
a : Option (α × WSeq α)
ma : a ∈ destruct (join S)
n : ℕ
h : Results (destruct (join S)) a n
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
clear ma
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
U : WSeq α → WSeq β → Prop
ST : LiftRel (LiftRel R) S T
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
a : Option (α × WSeq α)
n : ℕ
h : Results (destruct (join S)) a n
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
revert S T ST a
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
⊢ ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
    LiftRel (LiftRel R) S T →
      ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a n → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
induction' n using Nat.strongInductionOn with n IH
[GOAL]
case intro.ind
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
⊢ ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
    LiftRel (LiftRel R) S T →
      ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a n → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
intro S T ST a ra
[GOAL]
case intro.ind
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra : Results (destruct (join S)) a n
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
simp [destruct_join] at ra 
[GOAL]
case intro.ind
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
exact
  let ⟨o, m, k, rs1, rs2, en⟩ := of_results_bind ra
  let ⟨p, mT, rop⟩ := Computation.exists_of_LiftRel_left (liftRel_destruct ST) rs1.mem
  match o, p, rop, rs1, rs2, mT with
  | none, none, _, _, rs2, mT => by
    simp only [destruct_join]
    exact ⟨none, mem_bind mT (ret_mem _), by rw [eq_of_pure_mem rs2.mem]; trivial⟩
  | some (s, S'), some (t, T'), ⟨st, ST'⟩, _, rs2, mT =>
    by
    simp [destruct_append] at rs2 
    exact
      let ⟨k1, rs3, ek⟩ := of_results_think rs2
      let ⟨o', m1, n1, rs4, rs5, ek1⟩ := of_results_bind rs3
      let ⟨p', mt, rop'⟩ := Computation.exists_of_LiftRel_left (liftRel_destruct st) rs4.mem
      match o', p', rop', rs4, rs5, mt with
      | none, none, _, _, rs5', mt =>
        by
        have : n1 < n := by
          rw [en, ek, ek1]
          apply lt_of_lt_of_le _ (Nat.le_add_right _ _)
          apply Nat.lt_succ_of_le (Nat.le_add_right _ _)
        let ⟨ob, mb, rob⟩ := IH _ this ST' rs5'
        refine' ⟨ob, _, rob⟩
        · simp [destruct_join]
          apply mem_bind mT
          simp [destruct_append]
          apply think_mem
          apply mem_bind mt
          exact mb
      | some (a, s'), some (b, t'), ⟨ab, st'⟩, _, rs5, mt =>
        by
        simp at rs5 
        refine' ⟨some (b, append t' (join T')), _, _⟩
        · simp [destruct_join]
          apply mem_bind mT
          simp [destruct_append]
          apply think_mem
          apply mem_bind mt
          apply ret_mem
        rw [eq_of_pure_mem rs5.mem]
        exact ⟨ab, HU _ _ ⟨s', t', S', T', rfl, rfl, st', ST'⟩⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
x✝¹ : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) none none
x✝ : Results (destruct S) none m
rs2 :
  Results
    (match none with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
mT : none ∈ destruct T
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
simp only [destruct_join]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
x✝¹ : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) none none
x✝ : Results (destruct S) none m
rs2 :
  Results
    (match none with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
mT : none ∈ destruct T
⊢ ∃ b, b ∈ Computation.bind (destruct T) destruct_join.aux ∧ LiftRelO R U a b
[PROOFSTEP]
exact ⟨none, mem_bind mT (ret_mem _), by rw [eq_of_pure_mem rs2.mem]; trivial⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
x✝¹ : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) none none
x✝ : Results (destruct S) none m
rs2 :
  Results
    (match none with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
mT : none ∈ destruct T
⊢ LiftRelO R U a none
[PROOFSTEP]
rw [eq_of_pure_mem rs2.mem]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
x✝¹ : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) none none
x✝ : Results (destruct S) none m
rs2 :
  Results
    (match none with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
mT : none ∈ destruct T
⊢ LiftRelO R U none none
[PROOFSTEP]
trivial
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝ : Results (destruct S) (some (s, S')) m
rs2 :
  Results
    (match some (s, S') with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
mT : some (t, T') ∈ destruct T
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
simp [destruct_append] at rs2 
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
exact
  let ⟨k1, rs3, ek⟩ := of_results_think rs2
  let ⟨o', m1, n1, rs4, rs5, ek1⟩ := of_results_bind rs3
  let ⟨p', mt, rop'⟩ := Computation.exists_of_LiftRel_left (liftRel_destruct st) rs4.mem
  match o', p', rop', rs4, rs5, mt with
  | none, none, _, _, rs5', mt =>
    by
    have : n1 < n := by
      rw [en, ek, ek1]
      apply lt_of_lt_of_le _ (Nat.le_add_right _ _)
      apply Nat.lt_succ_of_le (Nat.le_add_right _ _)
    let ⟨ob, mb, rob⟩ := IH _ this ST' rs5'
    refine' ⟨ob, _, rob⟩
    · simp [destruct_join]
      apply mem_bind mT
      simp [destruct_append]
      apply think_mem
      apply mem_bind mt
      exact mb
  | some (a, s'), some (b, t'), ⟨ab, st'⟩, _, rs5, mt =>
    by
    simp at rs5 
    refine' ⟨some (b, append t' (join T')), _, _⟩
    · simp [destruct_join]
      apply mem_bind mT
      simp [destruct_append]
      apply think_mem
      apply mem_bind mt
      apply ret_mem
    rw [eq_of_pure_mem rs5.mem]
    exact ⟨ab, HU _ _ ⟨s', t', S', T', rfl, rfl, st', ST'⟩⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
have : n1 < n := by
  rw [en, ek, ek1]
  apply lt_of_lt_of_le _ (Nat.le_add_right _ _)
  apply Nat.lt_succ_of_le (Nat.le_add_right _ _)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
⊢ n1 < n
[PROOFSTEP]
rw [en, ek, ek1]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
⊢ n1 < n1 + m1 + 1 + m
[PROOFSTEP]
apply lt_of_lt_of_le _ (Nat.le_add_right _ _)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
⊢ n1 < n1 + m1 + 1
[PROOFSTEP]
apply Nat.lt_succ_of_le (Nat.le_add_right _ _)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
let ⟨ob, mb, rob⟩ := IH _ this ST' rs5'
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
[PROOFSTEP]
refine' ⟨ob, _, rob⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈ destruct (join T)
[PROOFSTEP]
simp [destruct_join]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈
    Computation.bind (destruct T) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S)))
[PROOFSTEP]
apply mem_bind mT
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈
    match some (t, T') with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S)))
[PROOFSTEP]
simp [destruct_append]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈
    Computation.think
      (Computation.bind (destruct t) fun x =>
        match x with
        | none => destruct (join T')
        | some (a, s) => Computation.pure (some (a, append s (join T'))))
[PROOFSTEP]
apply think_mem
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈
    Computation.bind (destruct t) fun x =>
      match x with
      | none => destruct (join T')
      | some (a, s) => Computation.pure (some (a, append s (join T')))
[PROOFSTEP]
apply mem_bind mt
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝² : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5 :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
x✝¹ : LiftRelO R (LiftRel R) none none
x✝ : Results (destruct s) none m1
rs5' :
  Results
    (match none with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a n1
mt : none ∈ destruct t
this : n1 < n
ob : Option (β × WSeq β)
mb : ob ∈ destruct (join T')
rob : LiftRelO R U a ob
⊢ ob ∈
    match none with
    | none => destruct (join T')
    | some (a, s) => Computation.pure (some (a, append s (join T')))
[PROOFSTEP]
exact mb
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 :
  Results
    (match some (a, s') with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
mt : some (b, t') ∈ destruct t
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a✝ b
[PROOFSTEP]
simp at rs5 
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a✝ b
[PROOFSTEP]
refine' ⟨some (b, append t' (join T')), _, _⟩
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈ destruct (join T)
[PROOFSTEP]
simp [destruct_join]
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈
    Computation.bind (destruct T) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S)))
[PROOFSTEP]
apply mem_bind mT
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈
    match some (t, T') with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S)))
[PROOFSTEP]
simp [destruct_append]
[GOAL]
case refine'_1
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈
    Computation.think
      (Computation.bind (destruct t) fun x =>
        match x with
        | none => destruct (join T')
        | some (a, s) => Computation.pure (some (a, append s (join T'))))
[PROOFSTEP]
apply think_mem
[GOAL]
case refine'_1.a
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈
    Computation.bind (destruct t) fun x =>
      match x with
      | none => destruct (join T')
      | some (a, s) => Computation.pure (some (a, append s (join T')))
[PROOFSTEP]
apply mem_bind mt
[GOAL]
case refine'_1.a
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ some (b, append t' (join T')) ∈
    match some (b, t') with
    | none => destruct (join T')
    | some (a, s) => Computation.pure (some (a, append s (join T')))
[PROOFSTEP]
apply ret_mem
[GOAL]
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ LiftRelO R U a✝ (some (b, append t' (join T')))
[PROOFSTEP]
rw [eq_of_pure_mem rs5.mem]
[GOAL]
case refine'_2
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
U : WSeq α → WSeq β → Prop
HU :
  ∀ (s1 : WSeq α) (s2 : WSeq β),
    (∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) → U s1 s2
n : ℕ
IH :
  ∀ (m : ℕ),
    m < n →
      ∀ {S : WSeq (WSeq α)} {T : WSeq (WSeq β)},
        LiftRel (LiftRel R) S T →
          ∀ {a : Option (α × WSeq α)}, Results (destruct (join S)) a m → ∃ b, b ∈ destruct (join T) ∧ LiftRelO R U a b
S : WSeq (WSeq α)
T : WSeq (WSeq β)
ST : LiftRel (LiftRel R) S T
a✝ : Option (α × WSeq α)
ra :
  Results
    (Computation.bind (destruct S) fun x =>
      match x with
      | none => Computation.pure none
      | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ n
o : Option (WSeq α × WSeq (WSeq α))
m k : ℕ
rs1 : Results (destruct S) o m
rs2✝ :
  Results
    (match o with
    | none => Computation.pure none
    | some (s, S) => Computation.think (destruct (append s (join S))))
    a✝ k
en : n = k + m
p : Option (WSeq β × WSeq (WSeq β))
mT✝ : p ∈ destruct T
rop : LiftRelO (LiftRel R) (LiftRel (LiftRel R)) o p
s : WSeq α
S' : WSeq (WSeq α)
t : WSeq β
T' : WSeq (WSeq β)
st : LiftRel R s t
ST' : LiftRel (LiftRel R) S' T'
x✝¹ : Results (destruct S) (some (s, S')) m
mT : some (t, T') ∈ destruct T
rs2 :
  Results
    (Computation.think
      (Computation.bind (destruct s) fun x =>
        match x with
        | none => destruct (join S')
        | some (a, s) => Computation.pure (some (a, append s (join S')))))
    a✝ k
k1 : ℕ
rs3 :
  Results
    (Computation.bind (destruct s) fun x =>
      match x with
      | none => destruct (join S')
      | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ k1
ek : k = k1 + 1
o' : Option (α × WSeq α)
m1 n1 : ℕ
rs4 : Results (destruct s) o' m1
rs5✝ :
  Results
    (match o' with
    | none => destruct (join S')
    | some (a, s) => Computation.pure (some (a, append s (join S'))))
    a✝ n1
ek1 : k1 = n1 + m1
p' : Option (β × WSeq β)
mt✝ : p' ∈ destruct t
rop' : LiftRelO R (LiftRel R) o' p'
a : α
s' : WSeq α
b : β
t' : WSeq β
ab : R a b
st' : LiftRel R s' t'
x✝ : Results (destruct s) (some (a, s')) m1
rs5 : Results (Computation.pure (some (a, append s' (join S')))) a✝ n1
mt : some (b, t') ∈ destruct t
⊢ LiftRelO R U (some (a, append s' (join S'))) (some (b, append t' (join T')))
[PROOFSTEP]
exact ⟨ab, HU _ _ ⟨s', t', S', T', rfl, rfl, st', ST'⟩⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h : LiftRel (LiftRel R) S T
⊢ join S = append nil (join S)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h : LiftRel (LiftRel R) S T
⊢ join T = append nil (join T)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h : LiftRel (LiftRel R) S T
⊢ LiftRel R nil nil
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
⊢ Computation.LiftRel
    (LiftRelO R fun s1 s2 =>
      ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
    (destruct s1) (destruct s2)
[PROOFSTEP]
rw [h1, h2]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
⊢ Computation.LiftRel
    (LiftRelO R fun s1 s2 =>
      ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
    (destruct (append s (join S))) (destruct (append t (join T)))
[PROOFSTEP]
rw [destruct_append, destruct_append]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
⊢ Computation.LiftRel
    (LiftRelO R fun s1 s2 =>
      ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
    (Computation.bind (destruct s) (destruct_append.aux (join S)))
    (Computation.bind (destruct t) (destruct_append.aux (join T)))
[PROOFSTEP]
apply Computation.liftRel_bind _ _ (liftRel_destruct st)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
⊢ ∀ {a : Option (α × WSeq α)} {b : Option (β × WSeq β)},
    LiftRelO R (LiftRel R) a b →
      Computation.LiftRel
        (LiftRelO R fun s1 s2 =>
          ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
        (destruct_append.aux (join S) a) (destruct_append.aux (join T) b)
[PROOFSTEP]
exact fun {o p} h =>
  match o, p, h with
  | some (a, s), some (b, t), ⟨h1, h2⟩ => by
    -- Porting note: These 2 theorems should be excluded.
    simp [-liftRel_pure_left, -liftRel_pure_right]
    exact ⟨h1, s, t, S, rfl, T, rfl, h2, ST⟩
  | none, none, _ => by
    -- Porting note: `LiftRelO` should be excluded.
    dsimp [destruct_append.aux, Computation.LiftRel, -LiftRelO]; constructor
    · intro
      apply liftRel_join.lem _ ST fun _ _ => id
    · intro b mb
      rw [← LiftRelO.swap]
      apply liftRel_join.lem (swap R)
      · rw [← LiftRel.swap R, ← LiftRel.swap]
        apply ST
      · rw [← LiftRel.swap R, ← LiftRel.swap (LiftRel R)]
        exact fun s1 s2 ⟨s, t, S, T, h1, h2, st, ST⟩ => ⟨t, s, T, S, h2, h1, st, ST⟩
      · exact mb
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s✝ : WSeq α
t✝ : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1✝ : s1 = append s✝ (join S)
h2✝ : s2 = append t✝ (join T)
st : LiftRel R s✝ t✝
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
a : α
s : WSeq α
b : β
t : WSeq β
h1 : R a b
h2 : LiftRel R s t
⊢ Computation.LiftRel
    (LiftRelO R fun s1 s2 =>
      ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
    (destruct_append.aux (join S) (some (a, s))) (destruct_append.aux (join T) (some (b, t)))
[PROOFSTEP]
simp [-liftRel_pure_left, -liftRel_pure_right]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s✝ : WSeq α
t✝ : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1✝ : s1 = append s✝ (join S)
h2✝ : s2 = append t✝ (join T)
st : LiftRel R s✝ t✝
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
a : α
s : WSeq α
b : β
t : WSeq β
h1 : R a b
h2 : LiftRel R s t
⊢ R a b ∧
    ∃ s_1 t_1 S_1,
      append s (join S) = append s_1 (join S_1) ∧
        ∃ x, append t (join T) = append t_1 (join x) ∧ LiftRel R s_1 t_1 ∧ LiftRel (LiftRel R) S_1 x
[PROOFSTEP]
exact ⟨h1, s, t, S, rfl, T, rfl, h2, ST⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
⊢ Computation.LiftRel
    (LiftRelO R fun s1 s2 =>
      ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
    (destruct_append.aux (join S) none) (destruct_append.aux (join T) none)
[PROOFSTEP]
dsimp [destruct_append.aux, Computation.LiftRel, -LiftRelO]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
⊢ (∀ {a : Option (α × WSeq α)},
      a ∈ destruct (join S) →
        ∃ b,
          b ∈ destruct (join T) ∧
            LiftRelO R
              (fun s1 s2 =>
                ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
              a b) ∧
    ∀ {b : Option (β × WSeq β)},
      b ∈ destruct (join T) →
        ∃ a,
          a ∈ destruct (join S) ∧
            LiftRelO R
              (fun s1 s2 =>
                ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
              a b
[PROOFSTEP]
constructor
[GOAL]
case left
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
⊢ ∀ {a : Option (α × WSeq α)},
    a ∈ destruct (join S) →
      ∃ b,
        b ∈ destruct (join T) ∧
          LiftRelO R
            (fun s1 s2 =>
              ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
            a b
[PROOFSTEP]
intro
[GOAL]
case left
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
a✝ : Option (α × WSeq α)
⊢ a✝ ∈ destruct (join S) →
    ∃ b,
      b ∈ destruct (join T) ∧
        LiftRelO R
          (fun s1 s2 =>
            ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
          a✝ b
[PROOFSTEP]
apply liftRel_join.lem _ ST fun _ _ => id
[GOAL]
case right
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
⊢ ∀ {b : Option (β × WSeq β)},
    b ∈ destruct (join T) →
      ∃ a,
        a ∈ destruct (join S) ∧
          LiftRelO R
            (fun s1 s2 =>
              ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
            a b
[PROOFSTEP]
intro b mb
[GOAL]
case right
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ ∃ a,
    a ∈ destruct (join S) ∧
      LiftRelO R
        (fun s1 s2 =>
          ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
        a b
[PROOFSTEP]
rw [← LiftRelO.swap]
[GOAL]
case right
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ ∃ a,
    a ∈ destruct (join S) ∧
      swap
        (LiftRelO (fun x y => R y x) fun s2 s1 =>
          ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T)
        a b
[PROOFSTEP]
apply liftRel_join.lem (swap R)
[GOAL]
case right.ST
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ LiftRel (LiftRel (swap R)) ?m.401693 S
[PROOFSTEP]
rw [← LiftRel.swap R, ← LiftRel.swap]
[GOAL]
case right.ST
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ swap (LiftRel (LiftRel R)) ?m.401693 S
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ WSeq (WSeq β)
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ WSeq (WSeq β)
[PROOFSTEP]
apply ST
[GOAL]
case right.HU
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ ∀ (s1 : WSeq β) (s2 : WSeq α),
    (∃ s t S T,
        s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel (swap R) s t ∧ LiftRel (LiftRel (swap R)) S T) →
      ∃ s t S T, s2 = append s (join S) ∧ s1 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T
[PROOFSTEP]
rw [← LiftRel.swap R, ← LiftRel.swap (LiftRel R)]
[GOAL]
case right.HU
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ ∀ (s1 : WSeq β) (s2 : WSeq α),
    (∃ s t S T,
        s1 = append s (join S) ∧ s2 = append t (join T) ∧ swap (LiftRel R) s t ∧ swap (LiftRel (LiftRel R)) S T) →
      ∃ s t S T, s2 = append s (join S) ∧ s1 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T
[PROOFSTEP]
exact fun s1 s2 ⟨s, t, S, T, h1, h2, st, ST⟩ => ⟨t, s, T, S, h2, h1, st, ST⟩
[GOAL]
case right.ma
α : Type u
β : Type v
γ : Type w
R : α → β → Prop
S✝ : WSeq (WSeq α)
T✝ : WSeq (WSeq β)
h✝ : LiftRel (LiftRel R) S✝ T✝
s1 : WSeq α
s2 : WSeq β
x✝¹ :
  (fun s1 s2 => ∃ s t S T, s1 = append s (join S) ∧ s2 = append t (join T) ∧ LiftRel R s t ∧ LiftRel (LiftRel R) S T) s1
    s2
s : WSeq α
t : WSeq β
S : WSeq (WSeq α)
T : WSeq (WSeq β)
h1 : s1 = append s (join S)
h2 : s2 = append t (join T)
st : LiftRel R s t
ST : LiftRel (LiftRel R) S T
o : Option (α × WSeq α)
p : Option (β × WSeq β)
h : LiftRelO R (LiftRel R) o p
x✝ : LiftRelO R (LiftRel R) none none
b : Option (β × WSeq β)
mb : b ∈ destruct (join T)
⊢ b ∈ destruct (join T)
[PROOFSTEP]
exact mb
[GOAL]
α : Type u
β : Type v
γ : Type w
s1 s2 : WSeq α
f1 f2 : α → WSeq β
h1 : s1 ~ʷ s2
h2 : ∀ (a : α), f1 a ~ʷ f2 a
a b : α
h : a = b
⊢ LiftRel (fun x x_1 => x = x_1) (f1 a) (f2 b)
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
s1 s2 : WSeq α
f1 f2 : α → WSeq β
h1 : s1 ~ʷ s2
h2 : ∀ (a : α), f1 a ~ʷ f2 a
a b : α
h : a = b
⊢ LiftRel (fun x x_1 => x = x_1) (f1 b) (f2 b)
[PROOFSTEP]
apply h2
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ join (ret s) ~ʷ s
[PROOFSTEP]
simp [ret]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ think s ~ʷ s
[PROOFSTEP]
apply think_equiv
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ join (map ret s) ~ʷ s
[PROOFSTEP]
refine' ⟨fun s1 s2 => join (map ret s2) = s1, rfl, _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ ∀ {s t : WSeq α},
    (fun s1 s2 => join (map ret s2) = s1) s t →
      Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1) (destruct s)
        (destruct t)
[PROOFSTEP]
intro s' s h
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : join (map ret s) = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1) (destruct s') (destruct s)
[PROOFSTEP]
rw [← h]
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : join (map ret s) = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (destruct (join (map ret s))) (destruct s)
[PROOFSTEP]
apply lift_rel_rec fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : join (map ret s) = s'
⊢ ∀ {ca cb : Computation (Option (α × WSeq α))},
    (∃ s, ca = destruct (join (map ret s)) ∧ cb = destruct s) →
      LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
        (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s) (Computation.destruct ca)
        (Computation.destruct cb)
[PROOFSTEP]
exact fun {c1 c2} h =>
  match c1, c2, h with
  | _, _, ⟨s, rfl, rfl⟩ => by
    clear h
    have :
      ∀ s,
        ∃ s' : WSeq α,
          (map (fun a => cons a nil) s).join.destruct = (map (fun a => cons a nil) s').join.destruct ∧
            destruct s = s'.destruct :=
      fun s => ⟨s, rfl, rfl⟩
    induction' s using WSeq.recOn with a s s <;> simp [ret, ret_mem, this, Option.exists]
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h✝ : join (map ret s✝) = s'
c1 c2 : Computation (Option (α × WSeq α))
h : ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret s)))) (Computation.destruct (destruct s))
[PROOFSTEP]
clear h
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : join (map ret s✝) = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret s)))) (Computation.destruct (destruct s))
[PROOFSTEP]
have :
  ∀ s,
    ∃ s' : WSeq α,
      (map (fun a => cons a nil) s).join.destruct = (map (fun a => cons a nil) s').join.destruct ∧
        destruct s = s'.destruct :=
  fun s => ⟨s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : join (map ret s✝) = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
this :
  ∀ (s : WSeq α),
    ∃ s',
      destruct (join (map (fun a => cons a nil) s)) = destruct (join (map (fun a => cons a nil) s')) ∧
        destruct s = destruct s'
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret s)))) (Computation.destruct (destruct s))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : join (map ret s) = s'
c1 c2 : Computation (Option (α × WSeq α))
this :
  ∀ (s : WSeq α),
    ∃ s',
      destruct (join (map (fun a => cons a nil) s)) = destruct (join (map (fun a => cons a nil) s')) ∧
        destruct s = destruct s'
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret nil)))) (Computation.destruct (destruct nil))
[PROOFSTEP]
simp [ret, ret_mem, this, Option.exists]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : join (map ret s✝) = s'
c1 c2 : Computation (Option (α × WSeq α))
this :
  ∀ (s : WSeq α),
    ∃ s',
      destruct (join (map (fun a => cons a nil) s)) = destruct (join (map (fun a => cons a nil) s')) ∧
        destruct s = destruct s'
a : α
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret (cons a s))))) (Computation.destruct (destruct (cons a s)))
[PROOFSTEP]
simp [ret, ret_mem, this, Option.exists]
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : join (map ret s✝) = s'
c1 c2 : Computation (Option (α × WSeq α))
this :
  ∀ (s : WSeq α),
    ∃ s',
      destruct (join (map (fun a => cons a nil) s)) = destruct (join (map (fun a => cons a nil) s')) ∧
        destruct s = destruct s'
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => join (map ret s2) = s1)
    (fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s)
    (Computation.destruct (destruct (join (map ret (think s))))) (Computation.destruct (destruct (think s)))
[PROOFSTEP]
simp [ret, ret_mem, this, Option.exists]
[GOAL]
case Hc
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : join (map ret s) = s'
⊢ ∃ s_1, destruct (join (map ret s)) = destruct (join (map ret s_1)) ∧ destruct s = destruct s_1
[PROOFSTEP]
exact ⟨s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
⊢ join (append S T) ~ʷ append (join S) (join T)
[PROOFSTEP]
refine'
  ⟨fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)),
    ⟨nil, S, T, by simp, by simp⟩, _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
⊢ join (append S T) = append nil (join (append S T))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
⊢ append (join S) (join T) = append nil (append (join S) (join T))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
⊢ ∀ {s t : WSeq α},
    (fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))) s t →
      Computation.LiftRel
        (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
          ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
        (destruct s) (destruct t)
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
⊢ Computation.LiftRel
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (destruct s1) (destruct s2)
[PROOFSTEP]
apply
  lift_rel_rec
    (fun c1 c2 =>
      ∃ (s : WSeq α) (S T : _),
        c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    _ _ _
    (let ⟨s, S, T, h1, h2⟩ := h
    ⟨s, S, T, congr_arg destruct h1, congr_arg destruct h2⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
⊢ ∀ {ca cb : Computation (Option (α × WSeq α))},
    (fun c1 c2 =>
          ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
        ca cb →
      LiftRelAux
        (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
          ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
        (fun c1 c2 =>
          ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
        (Computation.destruct ca) (Computation.destruct cb)
[PROOFSTEP]
rintro c1 c2 ⟨s, S, T, rfl, rfl⟩
[GOAL]
case intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
S T : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (append s (join (append S T)))))
    (Computation.destruct (destruct (append s (append (join S) (join T)))))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case intro.intro.intro.intro.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (append nil (join (append S T)))))
    (Computation.destruct (destruct (append nil (append (join S) (join T)))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
a : α
s : WSeq α
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (append (cons a s) (join (append S T)))))
    (Computation.destruct (destruct (append (cons a s) (append (join S) (join T)))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
s : WSeq α
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (append (think s) (join (append S T)))))
    (Computation.destruct (destruct (append (think s) (append (join S) (join T)))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append S T)))) (Computation.destruct (destruct (append (join S) (join T))))
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case intro.intro.intro.intro.h1.h1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append nil T))))
    (Computation.destruct (destruct (append (join nil) (join T))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
s : WSeq α
S : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append (cons s S) T))))
    (Computation.destruct (destruct (append (join (cons s S)) (join T))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (append (think S) T))))
    (Computation.destruct (destruct (append (join (think S)) (join T))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join T))) (Computation.destruct (destruct (join T)))
[PROOFSTEP]
induction' T using WSeq.recOn with s T T
[GOAL]
case intro.intro.intro.intro.h1.h1.h1
α : Type u
β : Type v
γ : Type w
S T : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join nil))) (Computation.destruct (destruct (join nil)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (cons s T)))) (Computation.destruct (destruct (join (cons s T))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h3
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ t = append s_1 (append (join S) (join T))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S T, c1 = destruct (append s (join (append S T))) ∧ c2 = destruct (append s (append (join S) (join T))))
    (Computation.destruct (destruct (join (think T)))) (Computation.destruct (destruct (join (think T))))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ ∃ s_1 S T_1,
    destruct (append s (join T)) = destruct (append s_1 (join (append S T_1))) ∧
      destruct (append s (join T)) = destruct (append s_1 (append (join S) (join T_1)))
[PROOFSTEP]
refine' ⟨s, nil, T, _, _⟩
[GOAL]
case intro.intro.intro.intro.h1.h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ destruct (append s (join T)) = destruct (append s (join (append nil T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : WSeq α
T : WSeq (WSeq α)
⊢ destruct (append s (join T)) = destruct (append s (append (join nil) (join T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h3
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ ∃ s S T_1,
    destruct (join T) = destruct (append s (join (append S T_1))) ∧
      destruct (join T) = destruct (append s (append (join S) (join T_1)))
[PROOFSTEP]
refine' ⟨nil, nil, T, _, _⟩
[GOAL]
case intro.intro.intro.intro.h1.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ destruct (join T) = destruct (append nil (join (append nil T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
S T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
⊢ destruct (join T) = destruct (append nil (append (join nil) (join T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T : WSeq (WSeq α)
s : WSeq α
S : WSeq (WSeq α)
⊢ ∃ s_1 S_1 T_1,
    destruct (append s (join (append S T))) = destruct (append s_1 (join (append S_1 T_1))) ∧
      destruct (append s (append (join S) (join T))) = destruct (append s_1 (append (join S_1) (join T_1)))
[PROOFSTEP]
exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
case intro.intro.intro.intro.h1.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ ∃ s S_1 T_1,
    destruct (join (append S T)) = destruct (append s (join (append S_1 T_1))) ∧
      destruct (append (join S) (join T)) = destruct (append s (append (join S_1) (join T_1)))
[PROOFSTEP]
refine' ⟨nil, S, T, _, _⟩
[GOAL]
case intro.intro.intro.intro.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ destruct (join (append S T)) = destruct (append nil (join (append S T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
T S : WSeq (WSeq α)
⊢ destruct (append (join S) (join T)) = destruct (append nil (append (join S) (join T)))
[PROOFSTEP]
simp
[GOAL]
case intro.intro.intro.intro.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
a : α
s : WSeq α
⊢ ∃ s_1 S_1 T_1,
    append s (join (append S T)) = append s_1 (join (append S_1 T_1)) ∧
      append s (append (join S) (join T)) = append s_1 (append (join S_1) (join T_1))
[PROOFSTEP]
exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
case intro.intro.intro.intro.h3
α : Type u
β : Type v
γ : Type w
S✝ T✝ : WSeq (WSeq α)
s1 s2 : WSeq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
S T : WSeq (WSeq α)
s : WSeq α
⊢ ∃ s_1 S_1 T_1,
    destruct (append s (join (append S T))) = destruct (append s_1 (join (append S_1 T_1))) ∧
      destruct (append s (append (join S) (join T))) = destruct (append s_1 (append (join S_1) (join T_1)))
[PROOFSTEP]
exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ bind s (ret ∘ f) ~ʷ map f s
[PROOFSTEP]
dsimp [bind]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ join (map (ret ∘ f) s) ~ʷ map f s
[PROOFSTEP]
rw [map_comp]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s : WSeq α
⊢ join (map ret (map f s)) ~ʷ map f s
[PROOFSTEP]
apply join_map_ret
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : α → WSeq β
⊢ bind (ret a) f ~ʷ f a
[PROOFSTEP]
simp [bind]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
⊢ map f (join S) = join (map (map f) S)
[PROOFSTEP]
apply Seq.eq_of_bisim fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
⊢ Seq.IsBisimulation fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
⊢ Seq.BisimO (fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)))
    (Seq.destruct s1) (Seq.destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, S, rfl, rfl⟩ => by
    induction' s using WSeq.recOn with a s s <;> simp
    · induction' S using WSeq.recOn with s S S <;> simp
      · exact ⟨map f s, S, rfl, rfl⟩
      · refine' ⟨nil, S, _, _⟩ <;> simp
    · exact ⟨_, _, rfl, rfl⟩
    · exact ⟨_, _, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
s : WSeq β
S : WSeq (WSeq α)
⊢ Seq.BisimO (fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)))
    (Seq.destruct (append s (map f (join S)))) (Seq.destruct (append s (join (map (map f) S))))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ Seq.BisimO (fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)))
    (Seq.destruct (append nil (map f (join S)))) (Seq.destruct (append nil (join (map (map f) S))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
a : β
s : WSeq β
⊢ Seq.BisimO (fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)))
    (Seq.destruct (append (cons a s) (map f (join S)))) (Seq.destruct (append (cons a s) (join (map (map f) S))))
[PROOFSTEP]
simp
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
s : WSeq β
⊢ Seq.BisimO (fun s1 s2 => ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S)))
    (Seq.destruct (append (think s) (map f (join S)))) (Seq.destruct (append (think s) (join (map (map f) S))))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ match Seq.destruct (map f (join S)), Seq.destruct (join (map (map f) S)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (map f (join S)) ∧ s' = append s_1 (join (map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
⊢ match Seq.destruct (map f (join nil)), Seq.destruct (join (map (map f) nil)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (map f (join S)) ∧ s' = append s_1 (join (map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
s : WSeq α
S : WSeq (WSeq α)
⊢ match Seq.destruct (map f (join (cons s S))), Seq.destruct (join (map (map f) (cons s S))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (map f (join S)) ∧ s' = append s_1 (join (map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ match Seq.destruct (map f (join (think S))), Seq.destruct (join (map (map f) (think S))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (map f (join S)) ∧ s' = append s_1 (join (map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
s : WSeq α
S : WSeq (WSeq α)
⊢ ∃ s_1 S_1,
    append (map f s) (map f (join S)) = append s_1 (map f (join S_1)) ∧
      append (map f s) (join (map (map f) S)) = append s_1 (join (map (map f) S_1))
[PROOFSTEP]
exact ⟨map f s, S, rfl, rfl⟩
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ ∃ s S_1, map f (join S) = append s (map f (join S_1)) ∧ join (map (map f) S) = append s (join (map (map f) S_1))
[PROOFSTEP]
refine' ⟨nil, S, _, _⟩
[GOAL]
case h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ map f (join S) = append nil (map f (join S))
[PROOFSTEP]
simp
[GOAL]
case h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
⊢ join (map (map f) S) = append nil (join (map (map f) S))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
a : β
s : WSeq β
⊢ ∃ s_1 S_1,
    append s (map f (join S)) = append s_1 (map f (join S_1)) ∧
      append s (join (map (map f) S)) = append s_1 (join (map (map f) S_1))
[PROOFSTEP]
exact ⟨_, _, rfl, rfl⟩
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : WSeq (WSeq α)
s1 s2 : Seq (Option β)
h : ∃ s S, s1 = append s (map f (join S)) ∧ s2 = append s (join (map (map f) S))
S : WSeq (WSeq α)
s : WSeq β
⊢ ∃ s_1 S_1,
    append s (map f (join S)) = append s_1 (map f (join S_1)) ∧
      append s (join (map (map f) S)) = append s_1 (join (map (map f) S_1))
[PROOFSTEP]
exact ⟨_, _, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
⊢ ∃ s S_1, map f (join S) = append s (map f (join S_1)) ∧ join (map (map f) S) = append s (join (map (map f) S_1))
[PROOFSTEP]
refine' ⟨nil, S, _, _⟩
[GOAL]
case r.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
⊢ map f (join S) = append nil (map f (join S))
[PROOFSTEP]
simp
[GOAL]
case r.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
S : WSeq (WSeq α)
⊢ join (map (map f) S) = append nil (join (map (map f) S))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
⊢ join (join SS) ~ʷ join (map join SS)
[PROOFSTEP]
refine'
  ⟨fun s1 s2 =>
    ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))),
    ⟨nil, nil, SS, by simp, by simp⟩, _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
⊢ join (join SS) = append nil (join (append nil (join SS)))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
⊢ join (map join SS) = append nil (append (join nil) (join (map join SS)))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
⊢ ∀ {s t : WSeq α},
    (fun s1 s2 =>
          ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
        s t →
      Computation.LiftRel
        (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
          ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
        (destruct s) (destruct t)
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
⊢ Computation.LiftRel
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (destruct s1) (destruct s2)
[PROOFSTEP]
apply
  lift_rel_rec
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    _ (destruct s1) (destruct s2)
    (let ⟨s, S, SS, h1, h2⟩ := h
    ⟨s, S, SS, by simp [h1], by simp [h2]⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
s : WSeq α
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
h1 : s1 = append s (join (append S (join SS)))
h2 : s2 = append s (append (join S) (join (map join SS)))
⊢ destruct s1 = destruct (append s (join (append S (join SS))))
[PROOFSTEP]
simp [h1]
[GOAL]
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
s : WSeq α
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
h1 : s1 = append s (join (append S (join SS)))
h2 : s2 = append s (append (join S) (join (map join SS)))
⊢ destruct s2 = destruct (append s (append (join S) (join (map join SS))))
[PROOFSTEP]
simp [h2]
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
⊢ ∀ {ca cb : Computation (Option (α × WSeq α))},
    (fun c1 c2 =>
          ∃ s S SS,
            c1 = destruct (append s (join (append S (join SS)))) ∧
              c2 = destruct (append s (append (join S) (join (map join SS)))))
        ca cb →
      LiftRelAux
        (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
          ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
        (fun c1 c2 =>
          ∃ s S SS,
            c1 = destruct (append s (join (append S (join SS)))) ∧
              c2 = destruct (append s (append (join S) (join (map join SS)))))
        (Computation.destruct ca) (Computation.destruct cb)
[PROOFSTEP]
intro c1 c2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h✝ : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
h :
  ∃ s S SS,
    c1 = destruct (append s (join (append S (join SS)))) ∧
      c2 = destruct (append s (append (join S) (join (map join SS))))
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct c1) (Computation.destruct c2)
[PROOFSTEP]
exact
  match c1, c2, h with
  | _, _, ⟨s, S, SS, rfl, rfl⟩ => by
    clear h
    induction' s using WSeq.recOn with a s s <;> simp
    · induction' S using WSeq.recOn with s S S <;> simp
      · induction' SS using WSeq.recOn with S SS SS <;> simp
        · refine' ⟨nil, S, SS, _, _⟩ <;> simp
        · refine' ⟨nil, nil, SS, _, _⟩ <;> simp
      · exact ⟨s, S, SS, rfl, rfl⟩
      · refine' ⟨nil, S, SS, _, _⟩ <;> simp
    · exact ⟨s, S, SS, rfl, rfl⟩
    · exact ⟨s, S, SS, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h✝ : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
h :
  ∃ s S SS,
    c1 = destruct (append s (join (append S (join SS)))) ∧
      c2 = destruct (append s (append (join S) (join (map join SS))))
s : WSeq α
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (append s (join (append S (join SS))))))
    (Computation.destruct (destruct (append s (append (join S) (join (map join SS))))))
[PROOFSTEP]
clear h
[GOAL]
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (append s (join (append S (join SS))))))
    (Computation.destruct (destruct (append s (append (join S) (join (map join SS))))))
[PROOFSTEP]
induction' s using WSeq.recOn with a s s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (append nil (join (append S (join SS))))))
    (Computation.destruct (destruct (append nil (append (join S) (join (map join SS))))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
a : α
s : WSeq α
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (append (cons a s) (join (append S (join SS))))))
    (Computation.destruct (destruct (append (cons a s) (append (join S) (join (map join SS))))))
[PROOFSTEP]
simp
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
s : WSeq α
⊢ LiftRelAux
    (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 =>
      ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS))))
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (append (think s) (join (append S (join SS))))))
    (Computation.destruct (destruct (append (think s) (append (join S) (join (map join SS))))))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (append S (join SS)))))
    (Computation.destruct (destruct (append (join S) (join (map join SS)))))
[PROOFSTEP]
induction' S using WSeq.recOn with s S S
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (append nil (join SS)))))
    (Computation.destruct (destruct (append (join nil) (join (map join SS)))))
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
s : WSeq α
S : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (append (cons s S) (join SS)))))
    (Computation.destruct (destruct (append (join (cons s S)) (join (map join SS)))))
[PROOFSTEP]
simp
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
S : WSeq (WSeq α)
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (append (think S) (join SS)))))
    (Computation.destruct (destruct (append (join (think S)) (join (map join SS)))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (join SS)))) (Computation.destruct (destruct (join (map join SS))))
[PROOFSTEP]
induction' SS using WSeq.recOn with S SS SS
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
SS : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (join nil)))) (Computation.destruct (destruct (join (map join nil))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (join (cons S SS)))))
    (Computation.destruct (destruct (join (map join (cons S SS)))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ LiftRelAux
    (fun x x_1 =>
      match x, x_1 with
      | none, none => True
      | some (a, s), some (b, t) =>
        a = b ∧
          ∃ s_1 S SS, s = append s_1 (join (append S (join SS))) ∧ t = append s_1 (append (join S) (join (map join SS)))
      | x, x_2 => False)
    (fun c1 c2 =>
      ∃ s S SS,
        c1 = destruct (append s (join (append S (join SS)))) ∧
          c2 = destruct (append s (append (join S) (join (map join SS)))))
    (Computation.destruct (destruct (join (join (think SS)))))
    (Computation.destruct (destruct (join (map join (think SS)))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ ∃ s S_1 SS_1,
    destruct (join (append S (join SS))) = destruct (append s (join (append S_1 (join SS_1)))) ∧
      destruct (append (join S) (join (map join SS))) = destruct (append s (append (join S_1) (join (map join SS_1))))
[PROOFSTEP]
refine' ⟨nil, S, SS, _, _⟩
[GOAL]
case h1.h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ destruct (join (append S (join SS))) = destruct (append nil (join (append S (join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
⊢ destruct (append (join S) (join (map join SS))) = destruct (append nil (append (join S) (join (map join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ ∃ s S SS_1,
    destruct (join (join SS)) = destruct (append s (join (append S (join SS_1)))) ∧
      destruct (join (map join SS)) = destruct (append s (append (join S) (join (map join SS_1))))
[PROOFSTEP]
refine' ⟨nil, nil, SS, _, _⟩
[GOAL]
case h1.h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ destruct (join (join SS)) = destruct (append nil (join (append nil (join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
⊢ destruct (join (map join SS)) = destruct (append nil (append (join nil) (join (map join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
s : WSeq α
S : WSeq (WSeq α)
⊢ ∃ s_1 S_1 SS_1,
    destruct (append s (join (append S (join SS)))) = destruct (append s_1 (join (append S_1 (join SS_1)))) ∧
      destruct (append s (append (join S) (join (map join SS)))) =
        destruct (append s_1 (append (join S_1) (join (map join SS_1))))
[PROOFSTEP]
exact ⟨s, S, SS, rfl, rfl⟩
[GOAL]
case h1.h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
S : WSeq (WSeq α)
⊢ ∃ s S_1 SS_1,
    destruct (join (append S (join SS))) = destruct (append s (join (append S_1 (join SS_1)))) ∧
      destruct (append (join S) (join (map join SS))) = destruct (append s (append (join S_1) (join (map join SS_1))))
[PROOFSTEP]
refine' ⟨nil, S, SS, _, _⟩
[GOAL]
case h1.h3.refine'_1
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
S : WSeq (WSeq α)
⊢ destruct (join (append S (join SS))) = destruct (append nil (join (append S (join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1.h3.refine'_2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
SS : WSeq (WSeq (WSeq α))
S : WSeq (WSeq α)
⊢ destruct (append (join S) (join (map join SS))) = destruct (append nil (append (join S) (join (map join SS))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
a : α
s : WSeq α
⊢ ∃ s_1 S_1 SS_1,
    append s (join (append S (join SS))) = append s_1 (join (append S_1 (join SS_1))) ∧
      append s (append (join S) (join (map join SS))) = append s_1 (append (join S_1) (join (map join SS_1)))
[PROOFSTEP]
exact ⟨s, S, SS, rfl, rfl⟩
[GOAL]
case h3
α : Type u
β : Type v
γ : Type w
SS✝ : WSeq (WSeq (WSeq α))
s1 s2 : WSeq α
h : ∃ s S SS, s1 = append s (join (append S (join SS))) ∧ s2 = append s (append (join S) (join (map join SS)))
c1 c2 : Computation (Option (α × WSeq α))
S : WSeq (WSeq α)
SS : WSeq (WSeq (WSeq α))
s : WSeq α
⊢ ∃ s_1 S_1 SS_1,
    destruct (append s (join (append S (join SS)))) = destruct (append s_1 (join (append S_1 (join SS_1)))) ∧
      destruct (append s (append (join S) (join (map join SS)))) =
        destruct (append s_1 (append (join S_1) (join (map join SS_1))))
[PROOFSTEP]
exact ⟨s, S, SS, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
f : α → WSeq β
g : β → WSeq γ
⊢ bind (bind s f) g ~ʷ bind s fun x => bind (f x) g
[PROOFSTEP]
simp [bind]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
f : α → WSeq β
g : β → WSeq γ
⊢ join (join (map (map g) (map f s))) ~ʷ join (map (fun x => join (map g (f x))) s)
[PROOFSTEP]
erw [← map_comp f (map g), map_comp (map g ∘ f) join]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : WSeq α
f : α → WSeq β
g : β → WSeq γ
⊢ join (join (map (map g ∘ f) s)) ~ʷ join (map join (map (map g ∘ f) s))
[PROOFSTEP]
apply join_join
