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

tactic: 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⟩
state_before: α : Type u
β : Type v
γ : Type w
s : WSeq α
⊢ s.length = Computation.map List.length s.toList
state_after: α : 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'))
            (l.length, s) ∧
        c2 =
          Computation.map List.length
            (Computation.corec
              (fun x =>
                match x with
                | (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))

tactic: intro s1 s2 h
state_before: α : 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'))
            (l.length, s) ∧
        c2 =
          Computation.map List.length
            (Computation.corec
              (fun x =>
                match x with
                | (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))
state_after: α : 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'))
          (l.length, s) ∧
      s2 =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match x with
              | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    s1.destruct s2.destruct

tactic: rcases h with ⟨l, s, h⟩
state_before: α : 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'))
          (l.length, s) ∧
      s2 =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match x with
              | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    s1.destruct s2.destruct
state_after: 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'))
        (l.length, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    s1.destruct s2.destruct

tactic: rw [h.left, h.right]
state_before: 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'))
        (l.length, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    s1.destruct s2.destruct
state_after: 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'))
        (l.length, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    (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'))
        (l.length, s)).destruct
    (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))).destruct

tactic: induction' s using WSeq.recOn with a s s <;> simp [toList, nil, cons, think, length]
state_before: 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'))
        (l.length, s) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))
⊢ 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'))
              (l.length, s) ∧
          c2 =
            Computation.map List.length
              (Computation.corec
                (fun x =>
                  match x with
                  | (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)))
    (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'))
        (l.length, s)).destruct
    (Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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))).destruct
state_after: case intro.intro.h2
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s1 s2 : Computation ℕ
l : List α
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'))
        (l.length, 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 l.reverse
              | 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.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l.length + 1, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l_1.length, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (a :: l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l_1, s_1))

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'))
        (l.length, s.think) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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.think))
⊢ ∃ l_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l.length, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l_1.length, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l_1, s_1))

tactic: refine ⟨a::l, s, ?_, ?_⟩ <;> simp
state_before: case intro.intro.h2
α : Type u
β : Type v
γ : Type w
s✝ : WSeq α
s1 s2 : Computation ℕ
l : List α
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'))
        (l.length, 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 l.reverse
              | 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.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l.length + 1, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l_1.length, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (a :: l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l_1, s_1))
state_after: no goals

tactic: refine ⟨l, s, ?_, ?_⟩ <;> simp
state_before: 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'))
        (l.length, s.think) ∧
    s2 =
      Computation.map List.length
        (Computation.corec
          (fun x =>
            match x with
            | (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.think))
⊢ ∃ l_1 s_1,
    Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l.length, s) =
        Computation.corec
          (fun x =>
            match Seq.destruct x.2 with
            | none => Sum.inl x.1
            | some (none, s') => Sum.inr (x.1, s')
            | some (some val, s') => Sum.inr (x.1 + 1, s'))
          (l_1.length, s_1) ∧
      Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l, s)) =
        Computation.map List.length
          (Computation.corec
            (fun x =>
              match Seq.destruct x.2 with
              | none => Sum.inl x.1.reverse
              | some (none, s') => Sum.inr (x.1, s')
              | some (some a, s') => Sum.inr (a :: x.1, s'))
            (l_1, s_1))
state_after: no goals