Theorem: Stream'.WSeq.join_map_ret
File: Mathlib/Data/Seq/WSeq.lean

tactic: refine' ⟨fun s1 s2 => join (map ret s2) = s1, rfl, _⟩
state_before: α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ join (map ret s) ~ʷ s

tactic: intro s' s h
state_before: α : 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)

tactic: rw [← h]
state_before: α : 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)

tactic: apply lift_rel_rec fun c1 c2 => ∃ s, c1 = destruct (join (map ret s)) ∧ c2 = destruct s
state_before: α : 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)

tactic: 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]
state_before: 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)

tactic: clear h
state_before: α : 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))

tactic: 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⟩
state_before: α : 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))

tactic: induction' s using WSeq.recOn with a s s <;> simp [ret, ret_mem, this, Option.exists]
state_before: α : 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))

tactic: exact ⟨s, rfl, rfl⟩
state_before: 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