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 α
⊢ (map ret s).join ~ʷ s
state_after: α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ ∀ {s t : WSeq α},
    (fun s1 s2 => (map ret s2).join = s1) s t →
      Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) s.destruct t.destruct

tactic: intro s' s h
state_before: α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ ∀ {s t : WSeq α},
    (fun s1 s2 => (map ret s2).join = s1) s t →
      Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) s.destruct t.destruct
state_after: α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) s'.destruct s.destruct

tactic: rw [← h]
state_before: α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) s'.destruct s.destruct
state_after: α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) (map ret s).join.destruct
    s.destruct

tactic: apply liftRel_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 : (map ret s).join = s'
⊢ Computation.LiftRel (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1) (map ret s).join.destruct
    s.destruct
state_after: case H
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ ∀ {ca cb : Computation (Option (α × WSeq α))},
    (∃ s, ca = (map ret s).join.destruct ∧ cb = s.destruct) →
      LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
        (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) ca.destruct cb.destruct

case Hc
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ ∃ s_1, (map ret s).join.destruct = (map ret s_1).join.destruct ∧ s.destruct = s_1.destruct

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 (config := { unfoldPartialApp := true }) [ret, ret_mem, this, Option.exists]
state_before: case H
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ ∀ {ca cb : Computation (Option (α × WSeq α))},
    (∃ s, ca = (map ret s).join.destruct ∧ cb = s.destruct) →
      LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
        (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) ca.destruct cb.destruct
state_after: no goals

tactic: clear h
state_before: α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h✝ : (map ret s✝).join = s'
c1 c2 : Computation (Option (α × WSeq α))
h : ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
    (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) (map ret s).join.destruct.destruct
    s.destruct.destruct
state_after: α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : (map ret s✝).join = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
    (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) (map ret s).join.destruct.destruct
    s.destruct.destruct

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 : (map ret s✝).join = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
    (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) (map ret s).join.destruct.destruct
    s.destruct.destruct
state_after: α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : (map ret s✝).join = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
this :
  ∀ (s : WSeq α),
    ∃ s',
      (map (fun a => cons a nil) s).join.destruct = (map (fun a => cons a nil) s').join.destruct ∧
        s.destruct = s'.destruct
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
    (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) (map ret s).join.destruct.destruct
    s.destruct.destruct

tactic: induction' s using WSeq.recOn with a s s <;>
  simp (config := { unfoldPartialApp := true }) [ret, ret_mem, this, Option.exists]
state_before: α : Type u
β : Type v
γ : Type w
s✝¹ s' s✝ : WSeq α
h : (map ret s✝).join = s'
c1 c2 : Computation (Option (α × WSeq α))
s : WSeq α
this :
  ∀ (s : WSeq α),
    ∃ s',
      (map (fun a => cons a nil) s).join.destruct = (map (fun a => cons a nil) s').join.destruct ∧
        s.destruct = s'.destruct
⊢ LiftRelAux (LiftRelO (fun x x_1 => x = x_1) fun s1 s2 => (map ret s2).join = s1)
    (fun c1 c2 => ∃ s, c1 = (map ret s).join.destruct ∧ c2 = s.destruct) (map ret s).join.destruct.destruct
    s.destruct.destruct
state_after: no goals

tactic: exact ⟨s, rfl, rfl⟩
state_before: case Hc
α : Type u
β : Type v
γ : Type w
s✝ s' s : WSeq α
h : (map ret s).join = s'
⊢ ∃ s_1, (map ret s).join.destruct = (map ret s_1).join.destruct ∧ s.destruct = s_1.destruct
state_after: no goals