l3lab/ntp-mathlib huggingface dataset:
theorem eq_of_bisim (bisim : IsBisimulation R) {s₁ s₂} (r : s₁ ~ s₂) : s₁ = s₂ := by
  apply Subtype.eq
  apply Stream'.eq_of_bisim fun x y => ∃ s s' : Seq α, s.1 = x ∧ s'.1 = y ∧ R s s'
  dsimp [Stream'.IsBisimulation]
  intro t₁ t₂ e
  exact
    match t₁, t₂, e with
    | _, _, ⟨s, s', rfl, rfl, r⟩ => by
      suffices head s = head s' ∧ R (tail s) (tail s') from
        And.imp id (fun r => ⟨tail s, tail s', by cases s; rfl, by cases s'; rfl, r⟩) this
      have := bisim r; revert r this
      apply recOn s _ _ <;> apply recOn s' _ _
      · intro r _
        constructor
        · rfl
        · assumption
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s x' s' _ this
        rw [destruct_cons, destruct_cons] at this
        rw [head_cons, head_cons, tail_cons, tail_cons]
        cases' this with h1 h2
        constructor
        

Proof state:
case intro.left
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s✝ s'✝ : Seq α
x : α
s : Seq α
x' : α
s' : Seq α
r✝ : R (cons x' s') (cons x s)
h1 : x' = x
h2 : R s' s
⊢ some x' = some x
case intro.right
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s✝ s'✝ : Seq α
x : α
s : Seq α
x' : α
s' : Seq α
r✝ : R (cons x' s') (cons x s)
h1 : x' = x
h2 : R s' s
⊢ R s' s

Next tactic:
rw [h1]
theorem eq_of_bisim (bisim : IsBisimulation R) {s₁ s₂} (r : s₁ ~ s₂) : s₁ = s₂ := by
  apply Subtype.eq
  apply Stream'.eq_of_bisim fun x y => ∃ s s' : Seq α, s.1 = x ∧ s'.1 = y ∧ R s s'
  dsimp [Stream'.IsBisimulation]
  intro t₁ t₂ e
  exact
    match t₁, t₂, e with
    | _, _, ⟨s, s', rfl, rfl, r⟩ => by
      suffices head s = head s' ∧ R (tail s) (tail s') from
        And.imp id (fun r => ⟨tail s, tail s', by cases s; rfl, by cases s'; rfl, r⟩) this
      have := bisim r; revert r this
      apply recOn s _ _ <;> apply recOn s' _ _
      · intro r _
        constructor
        · rfl
        · assumption
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s x' s' _ this
        rw [destruct_cons, destruct_cons] at this
        rw [head_cons, head_cons, tail_cons, tail_cons]
        cases' this with h1 h2
        constructor
        rw [h1]
        

Proof state:
case intro.right
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
t₁ t₂ : Stream' (Option α)
e : ∃ s s', ↑s = t₁ ∧ ↑s' = t₂ ∧ R s s'
s✝ s'✝ : Seq α
x : α
s : Seq α
x' : α
s' : Seq α
r✝ : R (cons x' s') (cons x s)
h1 : x' = x
h2 : R s' s
⊢ R s' s

Next tactic:
exact h2
theorem eq_of_bisim (bisim : IsBisimulation R) {s₁ s₂} (r : s₁ ~ s₂) : s₁ = s₂ := by
  apply Subtype.eq
  apply Stream'.eq_of_bisim fun x y => ∃ s s' : Seq α, s.1 = x ∧ s'.1 = y ∧ R s s'
  dsimp [Stream'.IsBisimulation]
  intro t₁ t₂ e
  exact
    match t₁, t₂, e with
    | _, _, ⟨s, s', rfl, rfl, r⟩ => by
      suffices head s = head s' ∧ R (tail s) (tail s') from
        And.imp id (fun r => ⟨tail s, tail s', by cases s; rfl, by cases s'; rfl, r⟩) this
      have := bisim r; revert r this
      apply recOn s _ _ <;> apply recOn s' _ _
      · intro r _
        constructor
        · rfl
        · assumption
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s _ this
        rw [destruct_nil, destruct_cons] at this
        exact False.elim this
      · intro x s x' s' _ this
        rw [destruct_cons, destruct_cons] at this
        rw [head_cons, head_cons, tail_cons, tail_cons]
        cases' this with h1 h2
        constructor
        rw [h1]
        exact h2
  

Proof state:
case a.a
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
⊢ ∃ s s', ↑s = ↑s₁ ∧ ↑s' = ↑s₂ ∧ R s s'

Next tactic:
exact ⟨s₁, s₂, rfl, rfl, r⟩
theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
f g : Seq α → Seq β
H : ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))
⊢ f s = g s

Next tactic:
refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s := by
  refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
f g : Seq α → Seq β
H : ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))
⊢ IsBisimulation fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s

Next tactic:
intro s1 s2 h
theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s := by
  refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
  intro s1 s2 h; 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
f g : Seq α → Seq β
H : ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))
s1 s2 : Seq β
h : ∃ s, s1 = f s ∧ s2 = g s
⊢ BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct s1) (destruct s2)

Next tactic:
rcases h with ⟨s, h1, h2⟩
theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s := by
  refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
  intro s1 s2 h; rcases h with ⟨s, h1, h2⟩
  

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ : Seq α
f g : Seq α → Seq β
H : ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))
s1 s2 : Seq β
s : Seq α
h1 : s1 = f s
h2 : s2 = g s
⊢ BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct s1) (destruct s2)

Next tactic:
rw [h1, h2]
theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s := by
  refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
  intro s1 s2 h; rcases h with ⟨s, h1, h2⟩
  rw [h1, h2]; 

Proof state:
case intro.intro
α : Type u
β : Type v
γ : Type w
s✝ : Seq α
f g : Seq α → Seq β
H : ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))
s1 s2 : Seq β
s : Seq α
h1 : s1 = f s
h2 : s2 = g s
⊢ BisimO (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) (destruct (f s)) (destruct (g s))

Next tactic:
apply H
/-- Embed a list as a sequence -/
@[coe]
def ofList (l : List α) : Seq α :=
  ⟨List.get? l, fun {n} h => by
    

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
n : ℕ
h : List.get? l n = none
⊢ List.get? l (n + 1) = none

Next tactic:
rw [List.get?_eq_none] at h ⊢
/-- Embed a list as a sequence -/
@[coe]
def ofList (l : List α) : Seq α :=
  ⟨List.get? l, fun {n} h => by
    rw [List.get?_eq_none] at h ⊢
    

Proof state:
α : Type u
β : Type v
γ : Type w
l : List α
n : ℕ
h : List.length l ≤ n
⊢ List.length l ≤ n + 1

Next tactic:
exact h.trans (Nat.le_succ n)
@[simp]
theorem ofList_cons (a : α) (l : List α) : ofList (a::l) = cons a (ofList l) := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ ↑(a :: l) = cons a ↑l

Next tactic:
ext1 (_ | n)
@[simp]
theorem ofList_cons (a : α) (l : List α) : ofList (a::l) = cons a (ofList l) := by
  ext1 (_ | n) <;> 

Proof state:
case h.zero
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ get? (↑(a :: l)) Nat.zero = get? (cons a ↑l) Nat.zero

Next tactic:
rfl
@[simp]
theorem ofList_cons (a : α) (l : List α) : ofList (a::l) = cons a (ofList l) := by
  ext1 (_ | n) <;> 

Proof state:
case h.succ
α : Type u
β : Type v
γ : Type w
a : α
l : List α
n : ℕ
⊢ get? (↑(a :: l)) (Nat.succ n) = get? (cons a ↑l) (Nat.succ n)

Next tactic:
rfl
/-- Embed an infinite stream as a sequence -/
@[coe]
def ofStream (s : Stream' α) : Seq α :=
  ⟨s.map some, fun {n} h => by 

Proof state:
α : Type u
β : Type v
γ : Type w
s : Stream' α
n : ℕ
h : map some s n = none
⊢ map some s (n + 1) = none

Next tactic:
contradiction
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
⊢ Stream'.map (Option.map f) s n = none → Stream'.map (Option.map f) s (n + 1) = none

Next tactic:
dsimp [Stream'.map, Stream'.get]
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      

Proof state:
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
⊢ Option.map f (s n) = none → Option.map f (s (n + 1)) = none

Next tactic:
induction' e : s n with e
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      induction' e : s n with e <;> 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
e : s n = none
⊢ Option.map f none = none → Option.map f (s (n + 1)) = none

Next tactic:
intro
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      induction' e : s n with e <;> 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
e✝ : α
e : s n = some e✝
⊢ Option.map f (some e✝) = none → Option.map f (s (n + 1)) = none

Next tactic:
intro
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      induction' e : s n with e <;> intro
      · 

Proof state:
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
e : s n = none
a✝ : Option.map f none = none
⊢ Option.map f (s (n + 1)) = none

Next tactic:
rw [al e]
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      induction' e : s n with e <;> intro
      · rw [al e]
        

Proof state:
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
e : s n = none
a✝ : Option.map f none = none
⊢ Option.map f none = none

Next tactic:
assumption
/-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  | ⟨s, al⟩ =>
    ⟨s.map (Option.map f), fun {n} => by
      dsimp [Stream'.map, Stream'.get]
      induction' e : s n with e <;> intro
      · rw [al e]
        assumption
      · 

Proof state:
case some
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
e✝ : α
e : s n = some e✝
a✝ : Option.map f (some e✝) = none
⊢ Option.map f (s (n + 1)) = none

Next tactic:
contradiction
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  

Proof state:
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ append nil s = s

Next tactic:
apply coinduction2
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; 

Proof state:
case H
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = append nil s ∧ s2 = s) (destruct (append nil s)) (destruct s)

Next tactic:
intro s
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  

Proof state:
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = append nil s ∧ s2 = s) (destruct (append nil s)) (destruct s)

Next tactic:
dsimp [append]
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; 

Proof state:
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    destruct
      (corec
        (fun x =>
          match destruct x.1 with
          | none =>
            match destruct x.2 with
            | none => none
            | some (a, b) => some (a, nil, b)
          | some (a, s₁') => some (a, s₁', x.2))
        (nil, s)),
    destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
rw [corec_eq]
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  

Proof state:
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    omap
      (corec fun x =>
        match destruct x.1 with
        | none =>
          match destruct x.2 with
          | none => none
          | some (a, b) => some (a, nil, b)
        | some (a, s₁') => some (a, s₁', x.2))
      (match destruct (nil, s).1 with
      | none =>
        match destruct (nil, s).2 with
        | none => none
        | some (a, b) => some (a, nil, b)
      | some (a, s₁') => some (a, s₁', (nil, s).2)),
    destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
dsimp [append]
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; 

Proof state:
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    match
      match destruct s with
      | none => none
      | some (a, b) => some (a, nil, b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            b),
    destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
apply recOn s _ _
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; apply recOn s _ _
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    match
      match destruct nil with
      | none => none
      | some (a, b) => some (a, nil, b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            b),
    destruct nil with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
trivial
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; apply recOn s _ _
  · trivial
  · 

Proof state:
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    match
      match
        match destruct (cons x s) with
        | none => none
        | some (a, b) => some (a, nil, b) with
      | none => none
      | some (a, b) =>
        some
          (a,
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              b),
      destruct (cons x s) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧
        ∃ s_1,
          s =
              corec
                (fun x =>
                  match destruct x.1 with
                  | none =>
                    match destruct x.2 with
                    | none => none
                    | some (a, b) => some (a, nil, b)
                  | some (a, s₁') => some (a, s₁', x.2))
                (nil, s_1) ∧
            s' = s_1
    | x, x_1 => False

Next tactic:
intro x s
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; apply recOn s _ _
  · trivial
  · intro x s
    

Proof state:
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ match
    match
      match destruct (cons x s) with
      | none => none
      | some (a, b) => some (a, nil, b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            b),
    destruct (cons x s) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
rw [destruct_cons]
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; apply recOn s _ _
  · trivial
  · intro x s
    rw [destruct_cons]
    

Proof state:
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ match
    match
      match some (x, s) with
      | none => none
      | some (a, b) => some (a, nil, b) with
    | none => none
    | some (a, b) =>
      some
        (a,
          corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            b),
    some (x, s) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.1 with
                | none =>
                  match destruct x.2 with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.2))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False

Next tactic:
dsimp
@[simp]
theorem nil_append (s : Seq α) : append nil s = s := by
  apply coinduction2; intro s
  dsimp [append]; rw [corec_eq]
  dsimp [append]; apply recOn s _ _
  · trivial
  · intro x s
    rw [destruct_cons]
    dsimp
    

Proof state:
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ x = x ∧
    ∃ s_1,
      corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            (nil, s) =
          corec
            (fun x =>
              match destruct x.1 with
              | none =>
                match destruct x.2 with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.2))
            (nil, s_1) ∧
        s = s_1

Next tactic:
exact ⟨rfl, s, rfl, rfl⟩
@[simp]
theorem cons_append (a : α) (s t) : append (cons a s) t = cons a (append s t) :=
  destruct_eq_cons <| by
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ destruct (append (cons a s) t) = some (a, append s t)

Next tactic:
dsimp [append]
@[simp]
theorem cons_append (a : α) (s t) : append (cons a s) t = cons a (append s t) :=
  destruct_eq_cons <| by
    dsimp [append]; 

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ destruct
      (corec
        (fun x =>
          match destruct x.1 with
          | none =>
            match destruct x.2 with
            | none => none
            | some (a, b) => some (a, nil, b)
          | some (a, s₁') => some (a, s₁', x.2))
        (cons a s, t)) =
    some
      (a,
        corec
          (fun x =>
            match destruct x.1 with
            | none =>
              match destruct x.2 with
              | none => none
              | some (a, b) => some (a, nil, b)
            | some (a, s₁') => some (a, s₁', x.2))
          (s, t))

Next tactic:
rw [corec_eq]
@[simp]
theorem cons_append (a : α) (s t) : append (cons a s) t = cons a (append s t) :=
  destruct_eq_cons <| by
    dsimp [append]; rw [corec_eq]
    

Proof state:
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ omap
      (corec fun x =>
        match destruct x.1 with
        | none =>
          match destruct x.2 with
          | none => none
          | some (a, b) => some (a, nil, b)
        | some (a, s₁') => some (a, s₁', x.2))
      (match destruct (cons a s, t).1 with
      | none =>
        match destruct (cons a s, t).2 with
        | none => none
        | some (a, b) => some (a, nil, b)
      | some (a_1, s₁') => some (a_1, s₁', (cons a s, t).2)) =
    some
      (a,
        corec
          (fun x =>
            match destruct x.1 with
            | none =>
              match destruct x.2 with
              | none => none
              | some (a, b) => some (a, nil, b)
            | some (a, s₁') => some (a, s₁', x.2))
          (s, t))

Next tactic:
dsimp [append]