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

Proof steps:
state_before: α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → s.head ~ t.head
state_after: α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o : Option α}, o ∈ s.head → o ∈ t.head
tactic: suffices ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o}, o ∈ head s → o ∈ head t from fun s t h o =>
    ⟨this h, this h.symm⟩
state_before: α : Type u
β : Type v
γ : Type w
⊢ ∀ {s t : WSeq α}, s ~ʷ t → ∀ {o : Option α}, o ∈ s.head → o ∈ t.head
state_after: α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
⊢ o ∈ t.head
tactic: intro s t h o ho
state_before: α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
⊢ o ∈ t.head
state_after: case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
⊢ o ∈ t.head
tactic: rcases @Computation.exists_of_mem_map _ _ _ _ (destruct s) ho with ⟨ds, dsm, dse⟩
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
⊢ o ∈ t.head
state_after: case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
⊢ Prod.fst <$> ds ∈ t.head
tactic: rw [← dse]
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
⊢ Prod.fst <$> ds ∈ t.head
state_after: case intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Prod.fst <$> ds ∈ t.head
tactic: cases' destruct_congr h with l r
state_before: case intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
⊢ Prod.fst <$> ds ∈ t.head
state_after: case intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) ds dt
⊢ Prod.fst <$> ds ∈ t.head
tactic: rcases l dsm with ⟨dt, dtm, dst⟩
state_before: case intro.intro.intro.intro.intro
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
ds : Option (α × WSeq α)
dsm : ds ∈ s.destruct
dse : Prod.fst <$> ds = o
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dt : Option (α × WSeq α)
dtm : dt ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) ds dt
⊢ Prod.fst <$> ds ∈ t.head
state_after: case intro.intro.intro.intro.intro.none.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ s.destruct
dse : Prod.fst <$> none = o
dtm : none ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) none none
⊢ Prod.fst <$> none ∈ t.head

case intro.intro.intro.intro.intro.none.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
dsm : none ∈ s.destruct
dse : Prod.fst <$> none = o
b : α × WSeq α
dtm : some b ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) none (some b)
⊢ Prod.fst <$> none ∈ t.head

case intro.intro.intro.intro.intro.some.none
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ s.destruct
dse : Prod.fst <$> some a = o
dtm : none ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) none
⊢ Prod.fst <$> some a ∈ t.head

case intro.intro.intro.intro.intro.some.some
α : Type u
β : Type v
γ : Type w
s t : WSeq α
h : s ~ʷ t
o : Option α
ho : o ∈ s.head
l : ∀ {a : Option (α × WSeq α)}, a ∈ s.destruct → ∃ b, b ∈ t.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
r : ∀ {b : Option (α × WSeq α)}, b ∈ t.destruct → ∃ a, a ∈ s.destruct ∧ BisimO (fun x x_1 => x ~ʷ x_1) a b
a : α × WSeq α
dsm : some a ∈ s.destruct
dse : Prod.fst <$> some a = o
b : α × WSeq α
dtm : some b ∈ t.destruct
dst : BisimO (fun x x_1 => x ~ʷ x_1) (some a) (some b)
⊢ Prod.fst <$> some a ∈ t.head
tactic: cases' ds with a <;> cases' dt with b