[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ IsSeq (some a :: ↑s)
[PROOFSTEP]
rintro (n | _) h
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
h : (some a :: ↑s) Nat.zero = none
⊢ (some a :: ↑s) (Nat.zero + 1) = none
[PROOFSTEP]
contradiction
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
n✝ : ℕ
h : (some a :: ↑s) (Nat.succ n✝) = none
⊢ (some a :: ↑s) (Nat.succ n✝ + 1) = none
[PROOFSTEP]
exact s.2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
x y : α
s t : Seq α
h : cons x s = cons y t
⊢ x = y
[PROOFSTEP]
rw [← Option.some_inj, ← get?_cons_zero, h, get?_cons_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
x y : α
s t : Seq α
h : cons x s = cons y t
n : ℕ
⊢ get? s n = get? t n
[PROOFSTEP]
simp_rw [← get?_cons_succ x s n, h, get?_cons_succ]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ TerminatedAt s n ↔ Option.isNone (get? s n) = true
[PROOFSTEP]
unfold TerminatedAt
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ get? s n = none ↔ Option.isNone (get? s n) = true
[PROOFSTEP]
cases s.get? n
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ none = none ↔ Option.isNone none = true
[PROOFSTEP]
simp
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
val✝ : α
⊢ some val✝ = none ↔ Option.isNone (some val✝) = true
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ¬Terminates s ↔ ∀ (n : ℕ), Option.isSome (get? s n) = true
[PROOFSTEP]
simp only [Terminates, TerminatedAt, ← Ne.def, Option.ne_none_iff_isSome, not_exists, iff_self]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n✝ : ℕ
n' : Stream'.tail (↑s) n✝ = none
⊢ Stream'.tail (↑s) (n✝ + 1) = none
[PROOFSTEP]
cases' s with f al
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
n✝ : ℕ
f : Stream' (Option α)
al : IsSeq f
n' : Stream'.tail (↑{ val := f, property := al }) n✝ = none
⊢ Stream'.tail (↑{ val := f, property := al }) (n✝ + 1) = none
[PROOFSTEP]
exact al n'
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
m n : ℕ
h : m ≤ n
⊢ get? s m = none → get? s n = none
[PROOFSTEP]
cases' s with f al
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
m n : ℕ
h : m ≤ n
f : Stream' (Option α)
al : IsSeq f
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } n = none
[PROOFSTEP]
induction' h with n _ IH
[GOAL]
case mk.refl
α : Type u
β : Type v
γ : Type w
m n : ℕ
f : Stream' (Option α)
al : IsSeq f
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } m = none
case mk.step
α : Type u
β : Type v
γ : Type w
m n✝ : ℕ
f : Stream' (Option α)
al : IsSeq f
n : ℕ
a✝ : Nat.le m n
IH : get? { val := f, property := al } m = none → get? { val := f, property := al } n = none
⊢ get? { val := f, property := al } m = none → get? { val := f, property := al } (Nat.succ n) = none
[PROOFSTEP]
exacts [id, fun h2 => al (IH h2)]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
aₙ : α
n m : ℕ
m_le_n : m ≤ n
s_nth_eq_some : get? s n = some aₙ
⊢ get? s n ≠ none
[PROOFSTEP]
simp [s_nth_eq_some]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
x✝ : a ∈ nil
w✝ : ℕ
h : some a = none
⊢ False
[PROOFSTEP]
injection h
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
f : Stream' (Option α)
al : IsSeq f
h✝ : a ∈ cons b { val := f, property := al }
h : some a = some b
⊢ a = b
[PROOFSTEP]
injection h
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
⊢ a = b ∨ a ∈ s → a ∈ cons b s
[PROOFSTEP]
rintro (rfl | m) <;> [apply mem_cons; exact mem_cons_of_mem _ m]
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
⊢ a = b ∨ a ∈ s → a ∈ cons b s
[PROOFSTEP]
rintro (rfl | m)
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ a ∈ cons a s
[PROOFSTEP]
apply mem_cons
[GOAL]
case inr
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
m : a ∈ s
⊢ a ∈ cons b s
[PROOFSTEP]
exact mem_cons_of_mem _ m
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ destruct s = none → s = nil
[PROOFSTEP]
dsimp [destruct]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Option.map (fun a' => (a', tail s)) (get? s 0) = none → s = nil
[PROOFSTEP]
induction' f0 : get? s 0
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
⊢ Option.map (fun a' => (a', tail s)) none = none → s = nil
[PROOFSTEP]
intro h
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
val✝ : α
f0 : get? s 0 = some val✝
⊢ Option.map (fun a' => (a', tail s)) (some val✝) = none → s = nil
[PROOFSTEP]
intro h
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ s = nil
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case none.a
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ ↑s = ↑nil
[PROOFSTEP]
funext n
[GOAL]
case none.a.h
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
n : ℕ
⊢ ↑s n = ↑nil n
[PROOFSTEP]
induction' n with n IH
[GOAL]
case none.a.h.zero
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
⊢ ↑s Nat.zero = ↑nil Nat.zero
case none.a.h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = none
n : ℕ
IH : ↑s n = ↑nil n
⊢ ↑s (Nat.succ n) = ↑nil (Nat.succ n)
[PROOFSTEP]
exacts [f0, s.2 IH]
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
val✝ : α
f0 : get? s 0 = some val✝
h : Option.map (fun a' => (a', tail s)) (some val✝) = none
⊢ s = nil
[PROOFSTEP]
contradiction
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
⊢ destruct s = some (a, s') → s = cons a s'
[PROOFSTEP]
dsimp [destruct]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
⊢ Option.map (fun a' => (a', tail s)) (get? s 0) = some (a, s') → s = cons a s'
[PROOFSTEP]
induction' f0 : get? s 0 with a'
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
⊢ Option.map (fun a' => (a', tail s)) none = some (a, s') → s = cons a s'
[PROOFSTEP]
intro h
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
a' : α
f0 : get? s 0 = some a'
⊢ Option.map (fun a' => (a', tail s)) (some a') = some (a, s') → s = cons a s'
[PROOFSTEP]
intro h
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
f0 : get? s 0 = none
h : Option.map (fun a' => (a', tail s)) none = some (a, s')
⊢ s = cons a s'
[PROOFSTEP]
contradiction
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
a : α
s' : Seq α
x✝ : Option α
f0✝ : get? s 0 = x✝
a' : α
f0 : get? s 0 = some a'
h : Option.map (fun a' => (a', tail s)) (some a') = some (a, s')
⊢ s = cons a s'
[PROOFSTEP]
cases' s with f al
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a'
h : Option.map (fun a' => (a', tail { val := f, property := al })) (some a') = some (a, s')
⊢ { val := f, property := al } = cons a s'
[PROOFSTEP]
injections _ h1 h2
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ { val := f, property := al } = cons a s'
[PROOFSTEP]
rw [← h2]
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ { val := f, property := al } = cons a (tail { val := f, property := al })
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ ↑{ val := f, property := al } = ↑(cons a (tail { val := f, property := al }))
[PROOFSTEP]
dsimp [tail, cons]
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a'
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = some a :: Stream'.tail f
[PROOFSTEP]
rw [h1] at f0 
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = some a :: Stream'.tail f
[PROOFSTEP]
rw [← f0]
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
a : α
s' : Seq α
x✝ : Option α
a' : α
f : Stream' (Option α)
al : IsSeq f
f0✝ : get? { val := f, property := al } 0 = x✝
f0 : get? { val := f, property := al } 0 = some a
h1 : a' = a
h2 : tail { val := f, property := al } = s'
⊢ f = get? { val := f, property := al } 0 :: Stream'.tail f
[PROOFSTEP]
exact (Stream'.eta f).symm
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ destruct (cons a { val := f, property := al }) = some (a, { val := f, property := al })
[PROOFSTEP]
unfold cons destruct Functor.map
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ instFunctorOption.1
      (fun a' =>
        (a',
          tail
            { val := some a :: ↑{ val := f, property := al },
              property :=
                (_ :
                  ∀ {n : ℕ},
                    (some a :: ↑{ val := f, property := al }) n = none →
                      (some a :: ↑{ val := f, property := al }) (n + 1) = none) }))
      (get?
        { val := some a :: ↑{ val := f, property := al },
          property :=
            (_ :
              ∀ {n : ℕ},
                (some a :: ↑{ val := f, property := al }) n = none →
                  (some a :: ↑{ val := f, property := al }) (n + 1) = none) }
        0) =
    some (a, { val := f, property := al })
[PROOFSTEP]
apply congr_arg fun s => some (a, s)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ tail
      { val := some a :: ↑{ val := f, property := al },
        property :=
          (_ :
            ∀ {n : ℕ},
              (some a :: ↑{ val := f, property := al }) n = none →
                (some a :: ↑{ val := f, property := al }) (n + 1) = none) } =
    { val := f, property := al }
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ ↑(tail
        { val := some a :: ↑{ val := f, property := al },
          property :=
            (_ :
              ∀ {n : ℕ},
                (some a :: ↑{ val := f, property := al }) n = none →
                  (some a :: ↑{ val := f, property := al }) (n + 1) = none) }) =
    ↑{ val := f, property := al }
[PROOFSTEP]
dsimp [tail]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ head s = Prod.fst <$> destruct s
[PROOFSTEP]
unfold destruct head
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ get? s 0 = Prod.fst <$> (fun a' => (a', tail s)) <$> get? s 0
[PROOFSTEP]
cases get? s 0
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ none = Prod.fst <$> (fun a' => (a', tail s)) <$> none
[PROOFSTEP]
rfl
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
s : Seq α
val✝ : α
⊢ some val✝ = Prod.fst <$> (fun a' => (a', tail s)) <$> some val✝
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ head (cons a s) = some a
[PROOFSTEP]
rw [head_eq_destruct, destruct_cons, Option.map_eq_map, Option.map_some']
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ tail (cons a s) = s
[PROOFSTEP]
cases' s with f al
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ tail (cons a { val := f, property := al }) = { val := f, property := al }
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case mk.a
α : Type u
β : Type v
γ : Type w
a : α
f : Stream' (Option α)
al : IsSeq f
⊢ ↑(tail (cons a { val := f, property := al })) = ↑{ val := f, property := al }
[PROOFSTEP]
dsimp [tail, cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
⊢ C s
[PROOFSTEP]
cases' H : destruct s with v
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
H : destruct s = none
⊢ C s
[PROOFSTEP]
rw [destruct_eq_nil H]
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
H : destruct s = none
⊢ C nil
[PROOFSTEP]
apply h1
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
v : Seq1 α
H : destruct s = some v
⊢ C s
[PROOFSTEP]
cases' v with a s'
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
a : α
s' : Seq α
H : destruct s = some (a, s')
⊢ C s
[PROOFSTEP]
rw [destruct_eq_cons H]
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
C : Seq α → Sort v
s : Seq α
h1 : C nil
h2 : (x : α) → (s : Seq α) → C (cons x s)
a : α
s' : Seq α
H : destruct s = some (a, s')
⊢ C (cons a s')
[PROOFSTEP]
apply h2
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s : Seq α
M : a ∈ s
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
⊢ C s
[PROOFSTEP]
cases' M with k e
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e : (fun b => some a = b) (nth (↑s) k)
⊢ C s
[PROOFSTEP]
unfold Stream'.nth at e 
[GOAL]
case intro
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e : (fun b => some a = b) (↑s k)
⊢ C s
[PROOFSTEP]
induction' k with k IH generalizing s
[GOAL]
case intro.zero
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
⊢ C s
[PROOFSTEP]
have TH : s = cons a (tail s) := by
  apply destruct_eq_cons
  unfold destruct get? Functor.map
  rw [← e]
  rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
⊢ s = cons a (tail s)
[PROOFSTEP]
apply destruct_eq_cons
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
⊢ destruct s = some (a, tail s)
[PROOFSTEP]
unfold destruct get? Functor.map
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
⊢ instFunctorOption.1 (fun a' => (a', tail s)) (↑s 0) = some (a, tail s)
[PROOFSTEP]
rw [← e]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
⊢ instFunctorOption.1 (fun a' => (a', tail s)) (some a) = some (a, tail s)
[PROOFSTEP]
rfl
[GOAL]
case intro.zero
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
TH : s = cons a (tail s)
⊢ C s
[PROOFSTEP]
rw [TH]
[GOAL]
case intro.zero
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k : ℕ
e✝ : (fun b => some a = b) (↑s✝ k)
s : Seq α
e : some a = ↑s Nat.zero
TH : s = cons a (tail s)
⊢ C (cons a (tail s))
[PROOFSTEP]
apply
  h1 _ _
    (Or.inl rfl)
      -- porting note: had to reshuffle `intro`
[GOAL]
case intro.succ
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
e : some a = ↑s (Nat.succ k)
⊢ C s
[PROOFSTEP]
revert e
[GOAL]
case intro.succ
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
⊢ some a = ↑s (Nat.succ k) → C s
[PROOFSTEP]
apply s.recOn _ fun b s' => _
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
⊢ some a = ↑nil (Nat.succ k) → C nil
[PROOFSTEP]
intro e
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
e : some a = ↑nil (Nat.succ k)
⊢ C nil
[PROOFSTEP]
injection e
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
⊢ ∀ (b : α) (s' : Seq α), some a = ↑(cons b s') (Nat.succ k) → C (cons b s')
[PROOFSTEP]
intro b s' e
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
b : α
s' : Seq α
e : some a = ↑(cons b s') (Nat.succ k)
⊢ C (cons b s')
[PROOFSTEP]
have h_eq : (cons b s').val (Nat.succ k) = s'.val k := by cases s'; rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
b : α
s' : Seq α
e : some a = ↑(cons b s') (Nat.succ k)
⊢ ↑(cons b s') (Nat.succ k) = ↑s' k
[PROOFSTEP]
cases s'
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
b : α
val✝ : Stream' (Option α)
property✝ : IsSeq val✝
e : some a = ↑(cons b { val := val✝, property := property✝ }) (Nat.succ k)
⊢ ↑(cons b { val := val✝, property := property✝ }) (Nat.succ k) = ↑{ val := val✝, property := property✝ } k
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
b : α
s' : Seq α
e : some a = ↑(cons b s') (Nat.succ k)
h_eq : ↑(cons b s') (Nat.succ k) = ↑s' k
⊢ C (cons b s')
[PROOFSTEP]
rw [h_eq] at e 
[GOAL]
α : Type u
β : Type v
γ : Type w
C : Seq α → Prop
a : α
s✝ : Seq α
h1 : ∀ (b : α) (s' : Seq α), a = b ∨ C s' → C (cons b s')
k✝ : ℕ
e✝ : (fun b => some a = b) (↑s✝ k✝)
k : ℕ
IH : ∀ {s : Seq α}, some a = ↑s k → C s
s : Seq α
b : α
s' : Seq α
e : some a = ↑s' k
h_eq : ↑(cons b s') (Nat.succ k) = ↑s' k
⊢ C (cons b s')
[PROOFSTEP]
apply h1 _ _ (Or.inr (IH e))
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
⊢ Seq α
[PROOFSTEP]
refine' ⟨Stream'.corec' (Corec.f f) (some b), fun {n} h => _⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
h : corec' (Corec.f f) (some b) n = none
⊢ corec' (Corec.f f) (some b) (n + 1) = none
[PROOFSTEP]
rw [Stream'.corec'_eq]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
h : corec' (Corec.f f) (some b) n = none
⊢ ((Corec.f f (some b)).fst :: corec' (Corec.f f) (Corec.f f (some b)).snd) (n + 1) = none
[PROOFSTEP]
change Stream'.corec' (Corec.f f) (Corec.f f (some b)).2 n = none
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
h : corec' (Corec.f f) (some b) n = none
⊢ corec' (Corec.f f) (Corec.f f (some b)).snd n = none
[PROOFSTEP]
revert h
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
⊢ corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (Corec.f f (some b)).snd n = none
[PROOFSTEP]
generalize some b = o
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
o : Option β
⊢ corec' (Corec.f f) o n = none → corec' (Corec.f f) (Corec.f f o).snd n = none
[PROOFSTEP]
revert o
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
⊢ ∀ (o : Option β), corec' (Corec.f f) o n = none → corec' (Corec.f f) (Corec.f f o).snd n = none
[PROOFSTEP]
induction' n with n IH
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
⊢ ∀ (o : Option β), corec' (Corec.f f) o Nat.zero = none → corec' (Corec.f f) (Corec.f f o).snd Nat.zero = none
[PROOFSTEP]
intro o
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
IH : ∀ (o : Option β), corec' (Corec.f f) o n = none → corec' (Corec.f f) (Corec.f f o).snd n = none
⊢ ∀ (o : Option β), corec' (Corec.f f) o (Nat.succ n) = none → corec' (Corec.f f) (Corec.f f o).snd (Nat.succ n) = none
[PROOFSTEP]
intro o
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
o : Option β
⊢ corec' (Corec.f f) o Nat.zero = none → corec' (Corec.f f) (Corec.f f o).snd Nat.zero = none
[PROOFSTEP]
change (Corec.f f o).1 = none → (Corec.f f (Corec.f f o).2).1 = none
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
o : Option β
⊢ (Corec.f f o).fst = none → (Corec.f f (Corec.f f o).snd).fst = none
[PROOFSTEP]
cases' o with b
[GOAL]
case zero.none
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
⊢ (Corec.f f none).fst = none → (Corec.f f (Corec.f f none).snd).fst = none
[PROOFSTEP]
intro h
[GOAL]
case zero.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
⊢ (Corec.f f (some b)).fst = none → (Corec.f f (Corec.f f (some b)).snd).fst = none
[PROOFSTEP]
intro h
[GOAL]
case zero.none
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h : (Corec.f f none).fst = none
⊢ (Corec.f f (Corec.f f none).snd).fst = none
[PROOFSTEP]
rfl
[GOAL]
case zero.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
h : (Corec.f f (some b)).fst = none
⊢ (Corec.f f (Corec.f f (some b)).snd).fst = none
[PROOFSTEP]
dsimp [Corec.f] at h 
[GOAL]
case zero.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
h :
  (match f b with
      | none => (none, none)
      | some (a, b') => (some a, some b')).fst =
    none
⊢ (Corec.f f (Corec.f f (some b)).snd).fst = none
[PROOFSTEP]
dsimp [Corec.f]
[GOAL]
case zero.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
h :
  (match f b with
      | none => (none, none)
      | some (a, b') => (some a, some b')).fst =
    none
⊢ (match
        (match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b')).snd with
      | none => (none, none)
      | some b =>
        match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    none
[PROOFSTEP]
revert h
[GOAL]
case zero.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
⊢ (match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
      none →
    (match
          (match f b with
            | none => (none, none)
            | some (a, b') => (some a, some b')).snd with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b')).fst =
      none
[PROOFSTEP]
cases' h₁ : f b with s
[GOAL]
case zero.some.none
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
h₁ : f b = none
⊢ (match none with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
      none →
    (match
          (match none with
            | none => (none, none)
            | some (a, b') => (some a, some b')).snd with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b')).fst =
      none
[PROOFSTEP]
intro h
[GOAL]
case zero.some.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
s : α × β
h₁ : f b = some s
⊢ (match some s with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
      none →
    (match
          (match some s with
            | none => (none, none)
            | some (a, b') => (some a, some b')).snd with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b')).fst =
      none
[PROOFSTEP]
intro h
[GOAL]
case zero.some.none
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
h₁ : f b = none
h :
  (match none with
      | none => (none, none)
      | some (a, b') => (some a, some b')).fst =
    none
⊢ (match
        (match none with
          | none => (none, none)
          | some (a, b') => (some a, some b')).snd with
      | none => (none, none)
      | some b =>
        match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    none
[PROOFSTEP]
rfl
[GOAL]
case zero.some.some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
s : α × β
h₁ : f b = some s
h :
  (match some s with
      | none => (none, none)
      | some (a, b') => (some a, some b')).fst =
    none
⊢ (match
        (match some s with
          | none => (none, none)
          | some (a, b') => (some a, some b')).snd with
      | none => (none, none)
      | some b =>
        match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    none
[PROOFSTEP]
cases' s with a b'
[GOAL]
case zero.some.some.mk
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b✝ b : β
a : α
b' : β
h₁ : f b = some (a, b')
h :
  (match some (a, b') with
      | none => (none, none)
      | some (a, b') => (some a, some b')).fst =
    none
⊢ (match
        (match some (a, b') with
          | none => (none, none)
          | some (a, b') => (some a, some b')).snd with
      | none => (none, none)
      | some b =>
        match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    none
[PROOFSTEP]
contradiction
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
IH : ∀ (o : Option β), corec' (Corec.f f) o n = none → corec' (Corec.f f) (Corec.f f o).snd n = none
o : Option β
⊢ corec' (Corec.f f) o (Nat.succ n) = none → corec' (Corec.f f) (Corec.f f o).snd (Nat.succ n) = none
[PROOFSTEP]
rw [Stream'.corec'_eq (Corec.f f) (Corec.f f o).2, Stream'.corec'_eq (Corec.f f) o]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
n : ℕ
IH : ∀ (o : Option β), corec' (Corec.f f) o n = none → corec' (Corec.f f) (Corec.f f o).snd n = none
o : Option β
⊢ ((Corec.f f o).fst :: corec' (Corec.f f) (Corec.f f o).snd) (Nat.succ n) = none →
    ((Corec.f f (Corec.f f o).snd).fst :: corec' (Corec.f f) (Corec.f f (Corec.f f o).snd).snd) (Nat.succ n) = none
[PROOFSTEP]
exact IH (Corec.f f o).2
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
⊢ destruct (corec f b) = omap (corec f) (f b)
[PROOFSTEP]
dsimp [corec, destruct, nth]
  -- porting note: next two lines were `change`...`with`...
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
⊢ Option.map
      (fun a' =>
        (a',
          tail
            { val := corec' (Corec.f f) (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (corec' (Corec.f f) (some b) 0) =
    match f b with
    | none => none
    | some (a, b) =>
      some
        (a,
          { val := corec' (Corec.f f) (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
have h : Stream'.corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).1 := rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
⊢ Option.map
      (fun a' =>
        (a',
          tail
            { val := corec' (Corec.f f) (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (corec' (Corec.f f) (some b) 0) =
    match f b with
    | none => none
    | some (a, b) =>
      some
        (a,
          { val := corec' (Corec.f f) (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
⊢ Option.map
      (fun a' =>
        (a',
          tail
            { val := corec' (Corec.f f) (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (Corec.f f (some b)).fst =
    match f b with
    | none => none
    | some (a, b) =>
      some
        (a,
          { val := corec' (Corec.f f) (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
dsimp [Corec.f]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
⊢ Option.map
      (fun a' =>
        (a',
          tail
            {
              val :=
                corec'
                  (fun x =>
                    match x with
                    | none => (none, none)
                    | some b =>
                      match f b with
                      | none => (none, none)
                      | some (a, b') => (some a, some b'))
                  (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    match f b with
    | none => none
    | some (a, b) =>
      some
        (a,
          {
            val :=
              corec'
                (fun x =>
                  match x with
                  | none => (none, none)
                  | some b =>
                    match f b with
                    | none => (none, none)
                    | some (a, b') => (some a, some b'))
                (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
induction' h : f b with s
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
h : f b = none
⊢ Option.map
      (fun a' =>
        (a',
          tail
            {
              val :=
                corec'
                  (fun x =>
                    match x with
                    | none => (none, none)
                    | some b =>
                      match f b with
                      | none => (none, none)
                      | some (a, b') => (some a, some b'))
                  (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (match none with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    match none with
    | none => none
    | some (a, b) =>
      some
        (a,
          {
            val :=
              corec'
                (fun x =>
                  match x with
                  | none => (none, none)
                  | some b =>
                    match f b with
                    | none => (none, none)
                    | some (a, b') => (some a, some b'))
                (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
rfl
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
s : α × β
h : f b = some s
⊢ Option.map
      (fun a' =>
        (a',
          tail
            {
              val :=
                corec'
                  (fun x =>
                    match x with
                    | none => (none, none)
                    | some b =>
                      match f b with
                      | none => (none, none)
                      | some (a, b') => (some a, some b'))
                  (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (match some s with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    match some s with
    | none => none
    | some (a, b) =>
      some
        (a,
          {
            val :=
              corec'
                (fun x =>
                  match x with
                  | none => (none, none)
                  | some b =>
                    match f b with
                    | none => (none, none)
                    | some (a, b') => (some a, some b'))
                (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
cases' s with a b'
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ Option.map
      (fun a' =>
        (a',
          tail
            {
              val :=
                corec'
                  (fun x =>
                    match x with
                    | none => (none, none)
                    | some b =>
                      match f b with
                      | none => (none, none)
                      | some (a, b') => (some a, some b'))
                  (some b),
              property :=
                (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }))
      (match some (a, b') with
        | none => (none, none)
        | some (a, b') => (some a, some b')).fst =
    match some (a, b') with
    | none => none
    | some (a, b) =>
      some
        (a,
          {
            val :=
              corec'
                (fun x =>
                  match x with
                  | none => (none, none)
                  | some b =>
                    match f b with
                    | none => (none, none)
                    | some (a, b') => (some a, some b'))
                (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) })
[PROOFSTEP]
dsimp [Corec.f]
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ some
      (a,
        tail
          {
            val :=
              corec'
                (fun x =>
                  match x with
                  | none => (none, none)
                  | some b =>
                    match f b with
                    | none => (none, none)
                    | some (a, b') => (some a, some b'))
                (some b),
            property :=
              (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }) =
    some
      (a,
        {
          val :=
            corec'
              (fun x =>
                match x with
                | none => (none, none)
                | some b =>
                  match f b with
                  | none => (none, none)
                  | some (a, b') => (some a, some b'))
              (some b'),
          property :=
            (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b') n = none → corec' (Corec.f f) (some b') (n + 1) = none) })
[PROOFSTEP]
apply congr_arg fun b' => some (a, b')
[GOAL]
case some.mk
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ tail
      {
        val :=
          corec'
            (fun x =>
              match x with
              | none => (none, none)
              | some b =>
                match f b with
                | none => (none, none)
                | some (a, b') => (some a, some b'))
            (some b),
        property :=
          (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) } =
    {
      val :=
        corec'
          (fun x =>
            match x with
            | none => (none, none)
            | some b =>
              match f b with
              | none => (none, none)
              | some (a, b') => (some a, some b'))
          (some b'),
      property := (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b') n = none → corec' (Corec.f f) (some b') (n + 1) = none) }
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ ↑(tail
        {
          val :=
            corec'
              (fun x =>
                match x with
                | none => (none, none)
                | some b =>
                  match f b with
                  | none => (none, none)
                  | some (a, b') => (some a, some b'))
              (some b),
          property :=
            (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b) n = none → corec' (Corec.f f) (some b) (n + 1) = none) }) =
    ↑{
        val :=
          corec'
            (fun x =>
              match x with
              | none => (none, none)
              | some b =>
                match f b with
                | none => (none, none)
                | some (a, b') => (some a, some b'))
            (some b'),
        property :=
          (_ : ∀ {n : ℕ}, corec' (Corec.f f) (some b') n = none → corec' (Corec.f f) (some b') (n + 1) = none) }
[PROOFSTEP]
dsimp [corec, tail]
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ Stream'.tail
      (corec'
        (fun x =>
          match x with
          | none => (none, none)
          | some b =>
            match f b with
            | none => (none, none)
            | some (a, b') => (some a, some b'))
        (some b)) =
    corec'
      (fun x =>
        match x with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b'))
      (some b')
[PROOFSTEP]
rw [Stream'.corec'_eq, Stream'.tail_cons]
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ corec'
      (fun x =>
        match x with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b'))
      (match some b with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b')).snd =
    corec'
      (fun x =>
        match x with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b'))
      (some b')
[PROOFSTEP]
dsimp [Corec.f]
[GOAL]
case some.mk.a
α : Type u
β : Type v
γ : Type w
f : β → Option (α × β)
b : β
h✝¹ : corec' (Corec.f f) (some b) 0 = (Corec.f f (some b)).fst
x✝ : Option (α × β)
h✝ : f b = x✝
a : α
b' : β
h : f b = some (a, b')
⊢ corec'
      (fun x =>
        match x with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b'))
      (match f b with
        | none => (none, none)
        | some (a, b') => (some a, some b')).snd =
    corec'
      (fun x =>
        match x with
        | none => (none, none)
        | some b =>
          match f b with
          | none => (none, none)
          | some (a, b') => (some a, some b'))
      (some b')
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
⊢ s₁ = s₂
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
⊢ ↑s₁ = ↑s₂
[PROOFSTEP]
apply Stream'.eq_of_bisim fun x y => ∃ s s' : Seq α, s.1 = x ∧ s'.1 = y ∧ R s s'
[GOAL]
case a.bisim
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
⊢ Stream'.IsBisimulation fun x y => ∃ s s', ↑s = x ∧ ↑s' = y ∧ R s s'
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'
[PROOFSTEP]
dsimp [Stream'.IsBisimulation]
[GOAL]
case a.bisim
α : Type u
β : Type v
γ : Type w
R : Seq α → Seq α → Prop
bisim : IsBisimulation R
s₁ s₂ : Seq α
r : R s₁ s₂
⊢ ∀ ⦃s₁ s₂ : Stream' (Option α)⦄,
    (∃ s s', ↑s = s₁ ∧ ↑s' = s₂ ∧ R s s') →
      Stream'.head s₁ = Stream'.head s₂ ∧ ∃ s s', ↑s = Stream'.tail s₁ ∧ ↑s' = Stream'.tail s₂ ∧ R s s'
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'
[PROOFSTEP]
intro t₁ t₂ e
[GOAL]
case a.bisim
α : 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'
⊢ Stream'.head t₁ = Stream'.head t₂ ∧ ∃ s s', ↑s = Stream'.tail t₁ ∧ ↑s' = Stream'.tail t₂ ∧ R s s'
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'
[PROOFSTEP]
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
[GOAL]
α : 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 α
r : R s s'
⊢ Stream'.head ↑s = Stream'.head ↑s' ∧ ∃ s_1 s'_1, ↑s_1 = Stream'.tail ↑s ∧ ↑s'_1 = Stream'.tail ↑s' ∧ R s_1 s'_1
[PROOFSTEP]
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
[GOAL]
α : 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 α
r✝ : R s s'
this : head s = head s' ∧ R (tail s) (tail s')
r : R (tail s) (tail s')
⊢ ↑(tail s) = Stream'.tail ↑s
[PROOFSTEP]
cases s
[GOAL]
case mk
α : 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' : Seq α
val✝ : Stream' (Option α)
property✝ : IsSeq val✝
r✝ : R { val := val✝, property := property✝ } s'
this : head { val := val✝, property := property✝ } = head s' ∧ R (tail { val := val✝, property := property✝ }) (tail s')
r : R (tail { val := val✝, property := property✝ }) (tail s')
⊢ ↑(tail { val := val✝, property := property✝ }) = Stream'.tail ↑{ val := val✝, property := property✝ }
[PROOFSTEP]
rfl
[GOAL]
α : 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 α
r✝ : R s s'
this : head s = head s' ∧ R (tail s) (tail s')
r : R (tail s) (tail s')
⊢ ↑(tail s') = Stream'.tail ↑s'
[PROOFSTEP]
cases s'
[GOAL]
case mk
α : 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 : Seq α
val✝ : Stream' (Option α)
property✝ : IsSeq val✝
r✝ : R s { val := val✝, property := property✝ }
this : head s = head { val := val✝, property := property✝ } ∧ R (tail s) (tail { val := val✝, property := property✝ })
r : R (tail s) (tail { val := val✝, property := property✝ })
⊢ ↑(tail { val := val✝, property := property✝ }) = Stream'.tail ↑{ val := val✝, property := property✝ }
[PROOFSTEP]
rfl
[GOAL]
α : 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 α
r : R s s'
⊢ head s = head s' ∧ R (tail s) (tail s')
[PROOFSTEP]
have := bisim r
[GOAL]
α : 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 α
r : R s s'
this : BisimO R (destruct s) (destruct s')
⊢ head s = head s' ∧ R (tail s) (tail s')
[PROOFSTEP]
revert r this
[GOAL]
α : 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 α
⊢ R s s' → BisimO R (destruct s) (destruct s') → head s = head s' ∧ R (tail s) (tail s')
[PROOFSTEP]
apply recOn s _ _
[GOAL]
α : 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 α
⊢ R nil s' → BisimO R (destruct nil) (destruct s') → head nil = head s' ∧ R (tail nil) (tail s')
[PROOFSTEP]
apply recOn s' _ _
[GOAL]
α : 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 α),
    R (cons x s) s' →
      BisimO R (destruct (cons x s)) (destruct s') → head (cons x s) = head s' ∧ R (tail (cons x s)) (tail s')
[PROOFSTEP]
apply recOn s' _ _
[GOAL]
α : 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 α
⊢ R nil nil → BisimO R (destruct nil) (destruct nil) → head nil = head nil ∧ R (tail nil) (tail nil)
[PROOFSTEP]
intro r _
[GOAL]
α : 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 α
r : R nil nil
this✝ : BisimO R (destruct nil) (destruct nil)
⊢ head nil = head nil ∧ R (tail nil) (tail nil)
[PROOFSTEP]
constructor
[GOAL]
case 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 α
r : R nil nil
this✝ : BisimO R (destruct nil) (destruct nil)
⊢ head nil = head nil
[PROOFSTEP]
rfl
[GOAL]
case 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 α
r : R nil nil
this✝ : BisimO R (destruct nil) (destruct nil)
⊢ R (tail nil) (tail nil)
[PROOFSTEP]
assumption
[GOAL]
α : 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 α),
    R nil (cons x s) →
      BisimO R (destruct nil) (destruct (cons x s)) → head nil = head (cons x s) ∧ R (tail nil) (tail (cons x s))
[PROOFSTEP]
intro x s _ this
[GOAL]
α : 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 α
r✝ : R nil (cons x s)
this : BisimO R (destruct nil) (destruct (cons x s))
⊢ head nil = head (cons x s) ∧ R (tail nil) (tail (cons x s))
[PROOFSTEP]
rw [destruct_nil, destruct_cons] at this 
[GOAL]
α : 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 α
r✝ : R nil (cons x s)
this : BisimO R none (some (x, s))
⊢ head nil = head (cons x s) ∧ R (tail nil) (tail (cons x s))
[PROOFSTEP]
exact False.elim this
[GOAL]
α : 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 α),
    R (cons x s) nil →
      BisimO R (destruct (cons x s)) (destruct nil) → head (cons x s) = head nil ∧ R (tail (cons x s)) (tail nil)
[PROOFSTEP]
intro x s _ this
[GOAL]
α : 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 α
r✝ : R (cons x s) nil
this : BisimO R (destruct (cons x s)) (destruct nil)
⊢ head (cons x s) = head nil ∧ R (tail (cons x s)) (tail nil)
[PROOFSTEP]
rw [destruct_nil, destruct_cons] at this 
[GOAL]
α : 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 α
r✝ : R (cons x s) nil
this : BisimO R (some (x, s)) none
⊢ head (cons x s) = head nil ∧ R (tail (cons x s)) (tail nil)
[PROOFSTEP]
exact False.elim this
[GOAL]
α : 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_1 : α) (s_1 : Seq α),
    R (cons x_1 s_1) (cons x s) →
      BisimO R (destruct (cons x_1 s_1)) (destruct (cons x s)) →
        head (cons x_1 s_1) = head (cons x s) ∧ R (tail (cons x_1 s_1)) (tail (cons x s))
[PROOFSTEP]
intro x s x' s' _ this
[GOAL]
α : 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)
this : BisimO R (destruct (cons x' s')) (destruct (cons x s))
⊢ head (cons x' s') = head (cons x s) ∧ R (tail (cons x' s')) (tail (cons x s))
[PROOFSTEP]
rw [destruct_cons, destruct_cons] at this 
[GOAL]
α : 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)
this : BisimO R (some (x', s')) (some (x, s))
⊢ head (cons x' s') = head (cons x s) ∧ R (tail (cons x' s')) (tail (cons x s))
[PROOFSTEP]
rw [head_cons, head_cons, tail_cons, tail_cons]
[GOAL]
α : 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)
this : BisimO R (some (x', s')) (some (x, s))
⊢ some x' = some x ∧ R s' s
[PROOFSTEP]
cases' this with h1 h2
[GOAL]
case intro
α : 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 ∧ R s' s
[PROOFSTEP]
constructor
[GOAL]
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
[PROOFSTEP]
rw [h1]
[GOAL]
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
[PROOFSTEP]
exact h2
[GOAL]
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'
[PROOFSTEP]
exact ⟨s₁, s₂, rfl, rfl, r⟩
[GOAL]
α : 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
[PROOFSTEP]
refine' eq_of_bisim (fun s1 s2 => ∃ s, s1 = f s ∧ s2 = g s) _ ⟨s, rfl, rfl⟩
[GOAL]
α : 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
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : 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)
[PROOFSTEP]
rcases h with ⟨s, h1, h2⟩
[GOAL]
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)
[PROOFSTEP]
rw [h1, h2]
[GOAL]
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))
[PROOFSTEP]
apply H
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
n : ℕ
h : List.get? l n = none
⊢ List.get? l (n + 1) = none
[PROOFSTEP]
rw [List.get?_eq_none] at h ⊢
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
n : ℕ
h : List.length l ≤ n
⊢ List.length l ≤ n + 1
[PROOFSTEP]
exact h.trans (Nat.le_succ n)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ ↑(a :: l) = cons a ↑l
[PROOFSTEP]
ext1 (_ | n)
[GOAL]
case h.zero
α : Type u
β : Type v
γ : Type w
a : α
l : List α
⊢ get? (↑(a :: l)) Nat.zero = get? (cons a ↑l) Nat.zero
[PROOFSTEP]
rfl
[GOAL]
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)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Stream' α
n : ℕ
h : map some s n = none
⊢ map some s (n + 1) = none
[PROOFSTEP]
contradiction
[GOAL]
α : 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
[PROOFSTEP]
dsimp [Stream'.map, Stream'.nth]
[GOAL]
α : 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
[PROOFSTEP]
induction' e : s n with e
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
x✝ : Option α
e✝ : s n = x✝
e : s n = none
⊢ Option.map f none = none → Option.map f (s (n + 1)) = none
[PROOFSTEP]
intro
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
x✝ : Option α
e✝¹ : s n = x✝
e✝ : α
e : s n = some e✝
⊢ Option.map f (some e✝) = none → Option.map f (s (n + 1)) = none
[PROOFSTEP]
intro
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
x✝ : Option α
e✝ : s n = x✝
e : s n = none
a✝ : Option.map f none = none
⊢ Option.map f (s (n + 1)) = none
[PROOFSTEP]
rw [al e]
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
x✝ : Option α
e✝ : s n = x✝
e : s n = none
a✝ : Option.map f none = none
⊢ Option.map f none = none
[PROOFSTEP]
assumption
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
n : ℕ
x✝ : Option α
e✝¹ : s n = x✝
e✝ : α
e : s n = some e✝
a✝ : Option.map f (some e✝) = none
⊢ Option.map f (s (n + 1)) = none
[PROOFSTEP]
contradiction
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ append nil s = s
[PROOFSTEP]
apply coinduction2
[GOAL]
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)
[PROOFSTEP]
intro s
[GOAL]
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)
[PROOFSTEP]
dsimp [append]
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    destruct
      (corec
        (fun x =>
          match destruct x.fst with
          | none =>
            match destruct x.snd with
            | none => none
            | some (a, b) => some (a, nil, b)
          | some (a, s₁') => some (a, s₁', x.snd))
        (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.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
rw [corec_eq]
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ match
    omap
      (corec fun x =>
        match destruct x.fst with
        | none =>
          match destruct x.snd with
          | none => none
          | some (a, b) => some (a, nil, b)
        | some (a, s₁') => some (a, s₁', x.snd))
      (match destruct (nil, s).fst with
      | none =>
        match destruct (nil, s).snd with
        | none => none
        | some (a, b) => some (a, nil, b)
      | some (a, s₁') => some (a, s₁', (nil, s).snd)),
    destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
dsimp [append]
[GOAL]
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.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            b),
    destruct s with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
apply recOn s _ _
[GOAL]
α : 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.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            b),
    destruct nil with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧
      ∃ s_1,
        s =
            corec
              (fun x =>
                match destruct x.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
trivial
[GOAL]
α : 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.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              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.fst with
                  | none =>
                    match destruct x.snd with
                    | none => none
                    | some (a, b) => some (a, nil, b)
                  | some (a, s₁') => some (a, s₁', x.snd))
                (nil, s_1) ∧
            s' = s_1
    | x, x_1 => False
[PROOFSTEP]
intro x s
[GOAL]
α : 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.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            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.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
rw [destruct_cons]
[GOAL]
α : 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.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            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.fst with
                | none =>
                  match destruct x.snd with
                  | none => none
                  | some (a, b) => some (a, nil, b)
                | some (a, s₁') => some (a, s₁', x.snd))
              (nil, s_1) ∧
          s' = s_1
  | x, x_1 => False
[PROOFSTEP]
dsimp
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ x = x ∧
    ∃ s_1,
      corec
            (fun x =>
              match destruct x.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            (nil, s) =
          corec
            (fun x =>
              match destruct x.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            (nil, s_1) ∧
        s = s_1
[PROOFSTEP]
exact ⟨rfl, s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ destruct (append (cons a s) t) = some (a, append s t)
[PROOFSTEP]
dsimp [append]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ destruct
      (corec
        (fun x =>
          match destruct x.fst with
          | none =>
            match destruct x.snd with
            | none => none
            | some (a, b) => some (a, nil, b)
          | some (a, s₁') => some (a, s₁', x.snd))
        (cons a s, t)) =
    some
      (a,
        corec
          (fun x =>
            match destruct x.fst with
            | none =>
              match destruct x.snd with
              | none => none
              | some (a, b) => some (a, nil, b)
            | some (a, s₁') => some (a, s₁', x.snd))
          (s, t))
[PROOFSTEP]
rw [corec_eq]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ omap
      (corec fun x =>
        match destruct x.fst with
        | none =>
          match destruct x.snd with
          | none => none
          | some (a, b) => some (a, nil, b)
        | some (a, s₁') => some (a, s₁', x.snd))
      (match destruct (cons a s, t).fst with
      | none =>
        match destruct (cons a s, t).snd with
        | none => none
        | some (a, b) => some (a, nil, b)
      | some (a_1, s₁') => some (a_1, s₁', (cons a s, t).snd)) =
    some
      (a,
        corec
          (fun x =>
            match destruct x.fst with
            | none =>
              match destruct x.snd with
              | none => none
              | some (a, b) => some (a, nil, b)
            | some (a, s₁') => some (a, s₁', x.snd))
          (s, t))
[PROOFSTEP]
dsimp [append]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s t : Seq α
⊢ (match
      match destruct (cons a s) with
      | none =>
        match destruct t with
        | none => none
        | some (a, b) => some (a, nil, b)
      | some (a, s₁') => some (a, s₁', t) with
    | none => none
    | some (a, b) =>
      some
        (a,
          corec
            (fun x =>
              match destruct x.fst with
              | none =>
                match destruct x.snd with
                | none => none
                | some (a, b) => some (a, nil, b)
              | some (a, s₁') => some (a, s₁', x.snd))
            b)) =
    some
      (a,
        corec
          (fun x =>
            match destruct x.fst with
            | none =>
              match destruct x.snd with
              | none => none
              | some (a, b) => some (a, nil, b)
            | some (a, s₁') => some (a, s₁', x.snd))
          (s, t))
[PROOFSTEP]
rw [destruct_cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ append s nil = s
[PROOFSTEP]
apply coinduction2 s
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ∀ (s : Seq α), BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (destruct (append s nil)) (destruct s)
[PROOFSTEP]
intro s
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (destruct (append s nil)) (destruct s)
[PROOFSTEP]
apply recOn s _ _
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (destruct (append nil nil)) (destruct nil)
[PROOFSTEP]
trivial
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (destruct (append (cons x s) nil)) (destruct (cons x s))
[PROOFSTEP]
intro x s
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (destruct (append (cons x s) nil)) (destruct (cons x s))
[PROOFSTEP]
rw [cons_append, destruct_cons, destruct_cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = append s nil ∧ s2 = s) (some (x, append s nil)) (some (x, s))
[PROOFSTEP]
dsimp
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝¹ s✝ : Seq α
x : α
s : Seq α
⊢ x = x ∧ ∃ s_1, append s nil = append s_1 nil ∧ s = s_1
[PROOFSTEP]
exact ⟨rfl, s, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s t u : Seq α
⊢ append (append s t) u = append s (append t u)
[PROOFSTEP]
apply eq_of_bisim fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
s t u : Seq α
⊢ IsBisimulation fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
[PROOFSTEP]
intro s1 s2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
s t u s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
⊢ BisimO (fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)) (destruct s1) (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, t, u, rfl, rfl⟩ => by
    apply recOn s <;> simp
    · apply recOn t <;> simp
      · apply recOn u <;> simp
        · intro _ u
          refine' ⟨nil, nil, u, _, _⟩ <;> simp
      · intro _ t
        refine' ⟨nil, t, u, _, _⟩ <;> simp
    · intro _ s
      exact ⟨s, t, u, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u))
    (destruct (append (append s t) u)) (destruct (append s (append t u)))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u))
    (destruct (append (append nil t) u)) (destruct (append nil (append t u)))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u))
      (destruct (append (append (cons x s) t) u)) (destruct (append (cons x s) (append t u)))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ match destruct (append t u), destruct (append t u) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
  | x, x_1 => False
[PROOFSTEP]
apply recOn t
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ match destruct (append nil u), destruct (append nil u) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ ∀ (x : α) (s : Seq α),
    match destruct (append (cons x s) u), destruct (append (cons x s) u) with
    | none, none => True
    | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ match destruct u, destruct u with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
  | x, x_1 => False
[PROOFSTEP]
apply recOn u
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ match destruct nil, destruct nil with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ ∀ (x : α) (s : Seq α),
    match destruct (cons x s), destruct (cons x s) with
    | none, none => True
    | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t u, s = append (append s_1 t) u ∧ s' = append s_1 (append t u)
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ α → ∀ (s : Seq α), ∃ s_1 t u, s = append (append s_1 t) u ∧ s = append s_1 (append t u)
[PROOFSTEP]
intro _ u
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝¹ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u✝ : Seq α
x✝ : α
u : Seq α
⊢ ∃ s t u_1, u = append (append s t) u_1 ∧ u = append s (append t u_1)
[PROOFSTEP]
refine' ⟨nil, nil, u, _, _⟩
[GOAL]
case h1.h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝¹ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u✝ : Seq α
x✝ : α
u : Seq α
⊢ u = append (append nil nil) u
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝¹ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u✝ : Seq α
x✝ : α
u : Seq α
⊢ u = append nil (append nil u)
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ α → ∀ (s : Seq α), ∃ s_1 t u_1, append s u = append (append s_1 t) u_1 ∧ append s u = append s_1 (append t u_1)
[PROOFSTEP]
intro _ t
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t✝ u : Seq α
x✝ : α
t : Seq α
⊢ ∃ s t_1 u_1, append t u = append (append s t_1) u_1 ∧ append t u = append s (append t_1 u_1)
[PROOFSTEP]
refine' ⟨nil, t, u, _, _⟩
[GOAL]
case h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t✝ u : Seq α
x✝ : α
t : Seq α
⊢ append t u = append (append nil t) u
[PROOFSTEP]
simp
[GOAL]
case h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
s✝ t✝¹ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t✝ u : Seq α
x✝ : α
t : Seq α
⊢ append t u = append nil (append t u)
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s✝ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s t u : Seq α
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 t_1 u_1,
        append (append s t) u = append (append s_1 t_1) u_1 ∧ append s (append t u) = append s_1 (append t_1 u_1)
[PROOFSTEP]
intro _ s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
s✝¹ t✝ u✝ s1 s2 : Seq α
h : ∃ s t u, s1 = append (append s t) u ∧ s2 = append s (append t u)
s✝ t u : Seq α
x✝ : α
s : Seq α
⊢ ∃ s_1 t_1 u_1,
    append (append s t) u = append (append s_1 t_1) u_1 ∧ append s (append t u) = append s_1 (append t_1 u_1)
[PROOFSTEP]
exact ⟨s, t, u, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
s t u : Seq α
⊢ ∃ s_1 t_1 u_1,
    append (append s t) u = append (append s_1 t_1) u_1 ∧ append s (append t u) = append s_1 (append t_1 u_1)
[PROOFSTEP]
exact ⟨s, t, u, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Stream' (Option α)
al : IsSeq s
⊢ map f (cons a { val := s, property := al }) = cons (f a) (map f { val := s, property := al })
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Stream' (Option α)
al : IsSeq s
⊢ ↑(map f (cons a { val := s, property := al })) = ↑(cons (f a) (map f { val := s, property := al }))
[PROOFSTEP]
dsimp [cons, map]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Stream' (Option α)
al : IsSeq s
⊢ Stream'.map (Option.map f) (some a :: s) = some (f a) :: Stream'.map (Option.map f) s
[PROOFSTEP]
rw [Stream'.map_cons]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Stream' (Option α)
al : IsSeq s
⊢ Option.map f (some a) :: Stream'.map (Option.map f) s = some (f a) :: Stream'.map (Option.map f) s
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Stream' (Option α)
al : IsSeq s
⊢ map id { val := s, property := al } = { val := s, property := al }
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s : Stream' (Option α)
al : IsSeq s
⊢ ↑(map id { val := s, property := al }) = ↑{ val := s, property := al }
[PROOFSTEP]
dsimp [map]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
s : Stream' (Option α)
al : IsSeq s
⊢ Stream'.map (Option.map id) s = s
[PROOFSTEP]
rw [Option.map_id, Stream'.map_id]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
⊢ map f (tail { val := s, property := al }) = tail (map f { val := s, property := al })
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
s : Stream' (Option α)
al : IsSeq s
⊢ ↑(map f (tail { val := s, property := al })) = ↑(tail (map f { val := s, property := al }))
[PROOFSTEP]
dsimp [tail, map]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ map (g ∘ f) { val := s, property := al } = map g (map f { val := s, property := al })
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ ↑(map (g ∘ f) { val := s, property := al }) = ↑(map g (map f { val := s, property := al }))
[PROOFSTEP]
dsimp [map]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ Stream'.map (Option.map (g ∘ f)) s = Stream'.map (Option.map g ∘ Option.map f) s
[PROOFSTEP]
apply congr_arg fun f : _ → Option γ => Stream'.map f s
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
⊢ Option.map (g ∘ f) = Option.map g ∘ Option.map f
[PROOFSTEP]
ext ⟨⟩
[GOAL]
case a.h.none.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) none ↔ a✝ ∈ (Option.map g ∘ Option.map f) none
[PROOFSTEP]
rfl
[GOAL]
case a.h.some.a
α : Type u
β : Type v
γ : Type w
f : α → β
g : β → γ
s : Stream' (Option α)
al : IsSeq s
val✝ : α
a✝ : γ
⊢ a✝ ∈ Option.map (g ∘ f) (some val✝) ↔ a✝ ∈ (Option.map g ∘ Option.map f) (some val✝)
[PROOFSTEP]
rfl
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
⊢ map f (append s t) = append (map f s) (map f t)
[PROOFSTEP]
apply eq_of_bisim (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) _ ⟨s, t, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
⊢ IsBisimulation fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s t : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) (destruct s1) (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, t, rfl, rfl⟩ => by
    apply recOn s <;> simp
    · apply recOn t <;> simp
      · intro _ t
        refine' ⟨nil, t, _, _⟩ <;> simp
    · intro _ s
      refine' ⟨s, t, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)) (destruct (map f (append s t)))
    (destruct (append (map f s) (map f t)))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t))
    (destruct (map f (append nil t))) (destruct (append (map f nil) (map f t)))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t))
      (destruct (map f (append (cons x s) t))) (destruct (append (map f (cons x s)) (map f t)))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ match destruct (map f t), destruct (map f t) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t, s = map f (append s_1 t) ∧ s' = append (map f s_1) (map f t)
  | x, x_1 => False
[PROOFSTEP]
apply recOn t
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ match destruct (map f nil), destruct (map f nil) with
  | none, none => True
  | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t, s = map f (append s_1 t) ∧ s' = append (map f s_1) (map f t)
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ ∀ (x : α) (s : Seq α),
    match destruct (map f (cons x s)), destruct (map f (cons x s)) with
    | none, none => True
    | some (a, s), some (a', s') => a = a' ∧ ∃ s_1 t, s = map f (append s_1 t) ∧ s' = append (map f s_1) (map f t)
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ α → ∀ (s : Seq α), ∃ s_1 t, map f s = map f (append s_1 t) ∧ map f s = append (map f s_1) (map f t)
[PROOFSTEP]
intro _ t
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ ∃ s t_1, map f t = map f (append s t_1) ∧ map f t = append (map f s) (map f t_1)
[PROOFSTEP]
refine' ⟨nil, t, _, _⟩
[GOAL]
case h1.h2.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ map f t = map f (append nil t)
[PROOFSTEP]
simp
[GOAL]
case h1.h2.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝¹ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t✝ : Seq α
x✝ : α
t : Seq α
⊢ map f t = append (map f nil) (map f t)
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s t : Seq α
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 t_1,
        map f (append s t) = map f (append s_1 t_1) ∧ append (map f s) (map f t) = append (map f s_1) (map f t_1)
[PROOFSTEP]
intro _ s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
s✝¹ t✝ : Seq α
s1 s2 : Seq β
h : ∃ s t, s1 = map f (append s t) ∧ s2 = append (map f s) (map f t)
s✝ t : Seq α
x✝ : α
s : Seq α
⊢ ∃ s_1 t_1, map f (append s t) = map f (append s_1 t_1) ∧ append (map f s) (map f t) = append (map f s_1) (map f t_1)
[PROOFSTEP]
refine' ⟨s, t, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
S : Seq (Seq1 α)
⊢ destruct (join (cons (a, nil) S)) = some (a, join S)
[PROOFSTEP]
simp [join]
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
S : Seq (Seq1 α)
⊢ destruct (join (cons (a, cons b s) S)) = some (a, join (cons (b, s) S))
[PROOFSTEP]
simp [join]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ join (cons (a, s) S) = cons a (append s (join S))
[PROOFSTEP]
apply
  eq_of_bisim (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) _
    (Or.inr ⟨a, s, S, rfl, rfl⟩)
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ IsBisimulation fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct s1)
    (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | s, _, Or.inl <| Eq.refl s => by
    apply recOn s; · trivial
    · intro x s
      rw [destruct_cons]
      exact ⟨rfl, Or.inl rfl⟩
  | _, _, Or.inr ⟨a, s, S, rfl, rfl⟩ => by
    apply recOn s
    · simp [join_cons_cons, join_cons_nil]
    · intro x s
      simp [join_cons_cons, join_cons_nil]
      refine' Or.inr ⟨x, s, S, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct s)
    (destruct s)
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (destruct nil)
    (destruct nil)
[PROOFSTEP]
trivial
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      (destruct (cons x s)) (destruct (cons x s))
[PROOFSTEP]
intro x s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝¹ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (cons x s)) (destruct (cons x s))
[PROOFSTEP]
rw [destruct_cons]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a : α
s✝¹ : Seq α
S : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
s✝ : Seq α
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))) (some (x, s))
    (some (x, s))
[PROOFSTEP]
exact ⟨rfl, Or.inl rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, s) S))) (destruct (cons a (append s (join S))))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, nil) S))) (destruct (cons a (append nil (join S))))
[PROOFSTEP]
simp [join_cons_cons, join_cons_nil]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
      (destruct (join (cons (a, cons x s) S))) (destruct (cons a (append (cons x s) (join S))))
[PROOFSTEP]
intro x s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝¹ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s✝ : Seq α
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ BisimO (fun s1 s2 => s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S)))
    (destruct (join (cons (a, cons x s) S))) (destruct (cons a (append (cons x s) (join S))))
[PROOFSTEP]
simp [join_cons_cons, join_cons_nil]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
a✝ : α
s✝¹ : Seq α
S✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : s1 = s2 ∨ ∃ a s S, s1 = join (cons (a, s) S) ∧ s2 = cons a (append s (join S))
a : α
s✝ : Seq α
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ join (cons (x, s) S) = cons x (append s (join S)) ∨
    ∃ a s_1 S_1,
      join (cons (x, s) S) = join (cons (a, s_1) S_1) ∧ cons x (append s (join S)) = cons a (append s_1 (join S_1))
[PROOFSTEP]
refine' Or.inr ⟨x, s, S, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ join (append S T) = append (join S) (join T)
[PROOFSTEP]
apply eq_of_bisim fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ IsBisimulation fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
⊢ BisimO (fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (destruct s1) (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, S, T, rfl, rfl⟩ => by
    apply recOn s <;> simp
    · apply recOn S <;> simp
      · apply recOn T
        · simp
        · intro s T
          cases' s with a s; simp
          refine' ⟨s, nil, T, _, _⟩ <;> simp
      · intro s S
        cases' s with a s; simp
        exact ⟨s, S, T, rfl, rfl⟩
    · intro _ s
      exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (destruct (append s (join (append S T)))) (destruct (append s (append (join S) (join T))))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
    (destruct (append nil (join (append S T)))) (destruct (append nil (append (join S) (join T))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T)))
      (destruct (append (cons x s) (join (append S T)))) (destruct (append (cons x s) (append (join S) (join T))))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ match destruct (join (append S T)), destruct (append (join S) (join T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
apply recOn S
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ match destruct (join (append nil T)), destruct (append (join nil) (join T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ ∀ (x : Seq1 α) (s : Seq (Seq1 α)),
    match destruct (join (append (cons x s) T)), destruct (append (join (cons x s)) (join T)) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ match destruct (join T), destruct (join T) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
apply recOn T
[GOAL]
case h1.h1.h1
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ match destruct (join nil), destruct (join nil) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ ∀ (x : Seq1 α) (s : Seq (Seq1 α)),
    match destruct (join (cons x s)), destruct (join (cons x s)) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
    | x, x_1 => False
[PROOFSTEP]
intro s T
[GOAL]
case h1.h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T✝ : Seq (Seq1 α)
s : Seq1 α
T : Seq (Seq1 α)
⊢ match destruct (join (cons s T)), destruct (join (cons s T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
cases' s with a s
[GOAL]
case h1.h1.h2.mk
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T✝ T : Seq (Seq1 α)
a : α
s : Seq α
⊢ match destruct (join (cons (a, s) T)), destruct (join (cons (a, s) T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2.mk
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T✝ T : Seq (Seq1 α)
a : α
s : Seq α
⊢ ∃ s_1 S T_1,
    append s (join T) = append s_1 (join (append S T_1)) ∧ append s (join T) = append s_1 (append (join S) (join T_1))
[PROOFSTEP]
refine' ⟨s, nil, T, _, _⟩
[GOAL]
case h1.h1.h2.mk.refine'_1
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T✝ T : Seq (Seq1 α)
a : α
s : Seq α
⊢ append s (join T) = append s (join (append nil T))
[PROOFSTEP]
simp
[GOAL]
case h1.h1.h2.mk.refine'_2
α : Type u
β : Type v
γ : Type w
S✝ T✝¹ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T✝ T : Seq (Seq1 α)
a : α
s : Seq α
⊢ append s (join T) = append s (append (join nil) (join T))
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ ∀ (x : Seq1 α) (s : Seq (Seq1 α)),
    match destruct (join (cons x (append s T))), destruct (append (join (cons x s)) (join T)) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
    | x, x_1 => False
[PROOFSTEP]
intro s S
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
S✝¹ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S✝ T : Seq (Seq1 α)
s : Seq1 α
S : Seq (Seq1 α)
⊢ match destruct (join (cons s (append S T))), destruct (append (join (cons s S)) (join T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
cases' s with a s
[GOAL]
case h1.h2.mk
α : Type u
β : Type v
γ : Type w
S✝¹ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S✝ T S : Seq (Seq1 α)
a : α
s : Seq α
⊢ match destruct (join (cons (a, s) (append S T))), destruct (append (join (cons (a, s) S)) (join T)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S T, s = append s_1 (join (append S T)) ∧ s' = append s_1 (append (join S) (join T))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2.mk
α : Type u
β : Type v
γ : Type w
S✝¹ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S✝ T S : Seq (Seq1 α)
a : α
s : Seq α
⊢ ∃ s_1 S_1 T_1,
    append s (join (append S T)) = append s_1 (join (append S_1 T_1)) ∧
      append s (append (join S) (join T)) = append s_1 (append (join S_1) (join T_1))
[PROOFSTEP]
exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s : Seq α
S T : Seq (Seq1 α)
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 S_1 T_1,
        append s (join (append S T)) = append s_1 (join (append S_1 T_1)) ∧
          append s (append (join S) (join T)) = append s_1 (append (join S_1) (join T_1))
[PROOFSTEP]
intro _ s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
S✝ T✝ : Seq (Seq1 α)
s1 s2 : Seq α
h : ∃ s S T, s1 = append s (join (append S T)) ∧ s2 = append s (append (join S) (join T))
s✝ : Seq α
S T : Seq (Seq1 α)
x✝ : α
s : Seq α
⊢ ∃ s_1 S_1 T_1,
    append s (join (append S T)) = append s_1 (join (append S_1 T_1)) ∧
      append s (append (join S) (join T)) = append s_1 (append (join S_1) (join T_1))
[PROOFSTEP]
exact ⟨s, S, T, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ ∃ s S_1 T_1,
    join (append S T) = append s (join (append S_1 T_1)) ∧
      append (join S) (join T) = append s (append (join S_1) (join T_1))
[PROOFSTEP]
refine' ⟨nil, S, T, _, _⟩
[GOAL]
case r.refine'_1
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ join (append S T) = append nil (join (append S T))
[PROOFSTEP]
simp
[GOAL]
case r.refine'_2
α : Type u
β : Type v
γ : Type w
S T : Seq (Seq1 α)
⊢ append (join S) (join T) = append nil (append (join S) (join T))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Stream' α
⊢ ↑(a :: s) = cons a ↑s
[PROOFSTEP]
apply Subtype.eq
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
a : α
s : Stream' α
⊢ ↑↑(a :: s) = ↑(cons a ↑s)
[PROOFSTEP]
simp [ofStream, cons]
[GOAL]
case a
α : Type u
β : Type v
γ : Type w
a : α
s : Stream' α
⊢ Stream'.map some (a :: s) = some a :: Stream'.map some s
[PROOFSTEP]
rw [Stream'.map_cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
l l' : List α
⊢ ↑(l ++ l') = append ↑l ↑l'
[PROOFSTEP]
induction l
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
l' : List α
⊢ ↑([] ++ l') = append ↑[] ↑l'
[PROOFSTEP]
simp [*]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
l' : List α
head✝ : α
tail✝ : List α
tail_ih✝ : ↑(tail✝ ++ l') = append ↑tail✝ ↑l'
⊢ ↑(head✝ :: tail✝ ++ l') = append ↑(head✝ :: tail✝) ↑l'
[PROOFSTEP]
simp [*]
[GOAL]
α : Type u
β : Type v
γ : Type w
l : List α
s : Stream' α
⊢ ↑(l ++ₛ s) = append ↑l ↑s
[PROOFSTEP]
induction l
[GOAL]
case nil
α : Type u
β : Type v
γ : Type w
s : Stream' α
⊢ ↑([] ++ₛ s) = append ↑[] ↑s
[PROOFSTEP]
simp [*, Stream'.nil_append_stream, Stream'.cons_append_stream]
[GOAL]
case cons
α : Type u
β : Type v
γ : Type w
s : Stream' α
head✝ : α
tail✝ : List α
tail_ih✝ : ↑(tail✝ ++ₛ s) = append ↑tail✝ ↑s
⊢ ↑(head✝ :: tail✝ ++ₛ s) = append ↑(head✝ :: tail✝) ↑s
[PROOFSTEP]
simp [*, Stream'.nil_append_stream, Stream'.cons_append_stream]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop (tail s) n = drop s (n + 1)
[PROOFSTEP]
rw [add_comm]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop (tail s) n = drop s (1 + n)
[PROOFSTEP]
symm
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ drop s (1 + n) = drop (tail s) n
[PROOFSTEP]
apply dropn_add
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
n : ℕ
⊢ head (drop s n) = get? s n
[PROOFSTEP]
induction' n with n IH generalizing s
[GOAL]
case zero
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ head (drop s Nat.zero) = get? s Nat.zero
[PROOFSTEP]
rfl
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s✝ : Seq α
n : ℕ
IH : ∀ (s : Seq α), head (drop s n) = get? s n
s : Seq α
⊢ head (drop s (Nat.succ n)) = get? s (Nat.succ n)
[PROOFSTEP]
rw [Nat.succ_eq_add_one, ← get?_tail, ← dropn_tail]
[GOAL]
case succ
α : Type u
β : Type v
γ : Type w
s✝ : Seq α
n : ℕ
IH : ∀ (s : Seq α), head (drop s n) = get? s n
s : Seq α
⊢ head (drop (tail s) n) = get? (tail s) n
[PROOFSTEP]
apply IH
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
h : b ∈ map f s
⊢ ∃ a, a ∈ s ∧ f a = b
[PROOFSTEP]
match s with
| ⟨g, al⟩ =>
  let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
  cases' o with a
  · injection oe
  · injection oe with h'; exact ⟨a, om, h'⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
let ⟨o, om, oe⟩ := @Stream'.exists_of_mem_map _ _ (Option.map f) (some b) g h
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
o : Option α
om : o ∈ g
oe : Option.map f o = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
cases' o with a
[GOAL]
case none
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
om : none ∈ g
oe : Option.map f none = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
injection oe
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ g
oe : Option.map f (some a) = some b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
injection oe with h'
[GOAL]
case some
α : Type u
β : Type v
γ : Type w
f : α → β
b : β
s : Seq α
g : Stream' (Option α)
al : IsSeq g
h : b ∈ map f { val := g, property := al }
a : α
om : some a ∈ g
h' : f a = b
⊢ ∃ a, a ∈ { val := g, property := al } ∧ f a = b
[PROOFSTEP]
exact ⟨a, om, h'⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
⊢ a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
have := h
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h this : a ∈ append s₁ s₂
⊢ a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
revert this
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
⊢ a ∈ append s₁ s₂ → a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
generalize e : append s₁ s₂ = ss
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ append s₁ s₂
ss : Seq α
e : append s₁ s₂ = ss
⊢ a ∈ ss → a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
intro h
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h✝ : a ∈ append s₁ s₂
ss : Seq α
e : append s₁ s₂ = ss
h : a ∈ ss
⊢ a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
revert s₁
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
⊢ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = ss → a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
apply mem_rec_on h _
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
⊢ ∀ (b : α) (s' : Seq α),
    (a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂) →
      ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = cons b s' → a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
intro b s' o s₁
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ a ∈ append s₁ s₂ → append s₁ s₂ = cons b s' → a ∈ s₁ ∨ a ∈ s₂
[PROOFSTEP]
apply s₁.recOn _ fun c t₁ => _
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ a ∈ append nil s₂ → append nil s₂ = cons b s' → a ∈ nil ∨ a ∈ s₂
[PROOFSTEP]
intro m _
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
m : a ∈ append nil s₂
e✝ : append nil s₂ = cons b s'
⊢ a ∈ nil ∨ a ∈ s₂
[PROOFSTEP]
apply Or.inr
[GOAL]
case h
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
m : a ∈ append nil s₂
e✝ : append nil s₂ = cons b s'
⊢ a ∈ s₂
[PROOFSTEP]
simpa using m
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
⊢ ∀ (c : α) (t₁ : Seq α), a ∈ append (cons c t₁) s₂ → append (cons c t₁) s₂ = cons b s' → a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
intro c t₁ m e
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
have this := congr_arg destruct e
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
cases' show a = c ∨ a ∈ append t₁ s₂ by simpa using m with e' m
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
⊢ a = c ∨ a ∈ append t₁ s₂
[PROOFSTEP]
simpa using m
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
e' : a = c
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
rw [e']
[GOAL]
case inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
e' : a = c
⊢ c ∈ cons c t₁ ∨ c ∈ s₂
[PROOFSTEP]
exact Or.inl (mem_cons _ _)
[GOAL]
case inr
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
cases' show c = b ∧ append t₁ s₂ = s' by simpa with i1 i2
[GOAL]
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
⊢ c = b ∧ append t₁ s₂ = s'
[PROOFSTEP]
simpa
[GOAL]
case inr.intro
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' : Seq α
o : a = b ∨ ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
cases' o with e' IH
[GOAL]
case inr.intro.inl
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
e' : a = b
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
simp [i1, e']
[GOAL]
case inr.intro.inr
α : Type u
β : Type v
γ : Type w
s₂ : Seq α
a : α
ss : Seq α
h : a ∈ ss
b : α
s' s₁ : Seq α
c : α
t₁ : Seq α
m✝ : a ∈ append (cons c t₁) s₂
e : append (cons c t₁) s₂ = cons b s'
this : destruct (append (cons c t₁) s₂) = destruct (cons b s')
m : a ∈ append t₁ s₂
i1 : c = b
i2 : append t₁ s₂ = s'
IH : ∀ {s₁ : Seq α}, a ∈ append s₁ s₂ → append s₁ s₂ = s' → a ∈ s₁ ∨ a ∈ s₂
⊢ a ∈ cons c t₁ ∨ a ∈ s₂
[PROOFSTEP]
exact Or.imp_left (mem_cons_of_mem _) (IH m i2)
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
⊢ a ∈ append s₁ s₂
[PROOFSTEP]
apply mem_rec_on h
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
⊢ ∀ (b : α) (s' : Seq α), a = b ∨ a ∈ append s' s₂ → a ∈ append (cons b s') s₂
[PROOFSTEP]
intros
[GOAL]
α : Type u
β : Type v
γ : Type w
s₁ s₂ : Seq α
a : α
h : a ∈ s₁
b✝ : α
s'✝ : Seq α
a✝ : a = b✝ ∨ a ∈ append s'✝ s₂
⊢ a ∈ append (cons b✝ s'✝) s₂
[PROOFSTEP]
simp [*]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
⊢ enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s))
[PROOFSTEP]
ext ⟨n⟩ : 1
[GOAL]
case h.zero
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
⊢ get? (enum (cons x s)) Nat.zero = get? (cons (0, x) (map (Prod.map Nat.succ id) (enum s))) Nat.zero
[PROOFSTEP]
simp
[GOAL]
case h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
n✝ : ℕ
⊢ get? (enum (cons x s)) (Nat.succ n✝) = get? (cons (0, x) (map (Prod.map Nat.succ id) (enum s))) (Nat.succ n✝)
[PROOFSTEP]
simp only [get?_enum, get?_cons_succ, map_get?, Option.map_map]
[GOAL]
case h.succ
α : Type u
β : Type v
γ : Type w
s : Seq α
x : α
n✝ : ℕ
⊢ Option.map (Prod.mk (Nat.succ n✝)) (get? s n✝) = Option.map (Prod.map Nat.succ id ∘ Prod.mk n✝) (get? s n✝)
[PROOFSTEP]
congr
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
s : Seq α
⊢ map id (a, s) = (a, s)
[PROOFSTEP]
simp [map]
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
S : Seq (Seq1 α)
⊢ join ((a, Seq.cons b s), S) = (a, Seq.join (Seq.cons (b, s) S))
[PROOFSTEP]
dsimp [join]
[GOAL]
α : Type u
β : Type v
γ : Type w
a b : α
s : Seq α
S : Seq (Seq1 α)
⊢ (match destruct (Seq.cons b s) with
    | none => (a, Seq.join S)
    | some s' => (a, Seq.join (Seq.cons s' S))) =
    (a, Seq.join (Seq.cons (b, s) S))
[PROOFSTEP]
rw [destruct_cons]
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ Seq.join (Seq.map ret s) = s
[PROOFSTEP]
apply coinduction2 s
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s : Seq α
⊢ ∀ (s : Seq α),
    BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret s))) (destruct s)
[PROOFSTEP]
intro s
[GOAL]
case H
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret s))) (destruct s)
[PROOFSTEP]
apply recOn s
[GOAL]
case H.h1
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret nil)))
    (destruct nil)
[PROOFSTEP]
simp [ret]
[GOAL]
case H.h2
α : Type u
β : Type v
γ : Type w
s✝ s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s, s1 = Seq.join (Seq.map ret s) ∧ s2 = s) (destruct (Seq.join (Seq.map ret (Seq.cons x s))))
      (destruct (Seq.cons x s))
[PROOFSTEP]
simp [ret]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ bind (a, s) (ret ∘ f) = map f (a, s)
[PROOFSTEP]
dsimp [bind, map]
  -- Porting note: Was `rw [map_comp]; simp [Function.comp, ret]`
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ join (ret (f a), Seq.map (ret ∘ f) s) = (f a, Seq.map f s)
[PROOFSTEP]
rw [map_comp, ret]
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
⊢ join ((f a, nil), Seq.map ret (Seq.map f s)) = (f a, Seq.map f s)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : α → Seq1 β
⊢ bind (ret a) f = f a
[PROOFSTEP]
simp [ret, bind, map]
[GOAL]
α : Type u
β : Type v
γ : Type w
a : α
f : α → Seq1 β
⊢ join (f a, nil) = f a
[PROOFSTEP]
cases' f a with a s
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, s), nil) = (a, s)
[PROOFSTEP]
apply recOn s
[GOAL]
case mk.h1
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, nil), nil) = (a, nil)
[PROOFSTEP]
intros
[GOAL]
case mk.h2
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ ∀ (x : β) (s : Seq β), join ((a, Seq.cons x s), nil) = (a, Seq.cons x s)
[PROOFSTEP]
intros
[GOAL]
case mk.h1
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
⊢ join ((a, nil), nil) = (a, nil)
[PROOFSTEP]
simp
[GOAL]
case mk.h2
α : Type u
β : Type v
γ : Type w
a✝ : α
f : α → Seq1 β
a : β
s : Seq β
x✝ : β
s✝ : Seq β
⊢ join ((a, Seq.cons x✝ s✝), nil) = (a, Seq.cons x✝ s✝)
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S)
[PROOFSTEP]
apply
  Seq.eq_of_bisim fun s1 s2 =>
    ∃ s S, s1 = Seq.append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.IsBisimulation fun s1 s2 =>
    ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
⊢ BisimO (fun s1 s2 => ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S)))
    (destruct s1) (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, S, rfl, rfl⟩ => by
    apply recOn s <;> simp
    · apply recOn S <;> simp
      · intro x S
        cases' x with a s; simp [map]
        exact ⟨_, _, rfl, rfl⟩
    · intro _ s
      refine' ⟨s, S, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S)))
    (destruct (append s (Seq.map f (Seq.join S)))) (destruct (append s (Seq.join (Seq.map (map f) S))))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ BisimO (fun s1 s2 => ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S)))
    (destruct (append nil (Seq.map f (Seq.join S)))) (destruct (append nil (Seq.join (Seq.map (map f) S))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ ∀ (x : β) (s : Seq β),
    BisimO (fun s1 s2 => ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S)))
      (destruct (append (Seq.cons x s) (Seq.map f (Seq.join S))))
      (destruct (append (Seq.cons x s) (Seq.join (Seq.map (map f) S))))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ match destruct (Seq.map f (Seq.join S)), destruct (Seq.join (Seq.map (map f) S)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
apply recOn S
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ match destruct (Seq.map f (Seq.join nil)), destruct (Seq.join (Seq.map (map f) nil)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ ∀ (x : Seq1 α) (s : Seq (Seq1 α)),
    match destruct (Seq.map f (Seq.join (Seq.cons x s))), destruct (Seq.join (Seq.map (map f) (Seq.cons x s))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ ∀ (x : Seq1 α) (s : Seq (Seq1 α)),
    match destruct (Seq.map f (Seq.join (Seq.cons x s))),
      destruct (Seq.join (Seq.cons (map f x) (Seq.map (map f) s))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
    | x, x_1 => False
[PROOFSTEP]
intro x S
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝¹ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S✝ : Seq (Seq1 α)
x : Seq1 α
S : Seq (Seq1 α)
⊢ match destruct (Seq.map f (Seq.join (Seq.cons x S))),
    destruct (Seq.join (Seq.cons (map f x) (Seq.map (map f) S))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
cases' x with a s
[GOAL]
case h1.h2.mk
α : Type u
β : Type v
γ : Type w
f : α → β
S✝¹ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s✝ : Seq β
S✝ S : Seq (Seq1 α)
a : α
s : Seq α
⊢ match destruct (Seq.map f (Seq.join (Seq.cons (a, s) S))),
    destruct (Seq.join (Seq.cons (map f (a, s)) (Seq.map (map f) S))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 S, s = append s_1 (Seq.map f (Seq.join S)) ∧ s' = append s_1 (Seq.join (Seq.map (map f) S))
  | x, x_1 => False
[PROOFSTEP]
simp [map]
[GOAL]
case h1.h2.mk
α : Type u
β : Type v
γ : Type w
f : α → β
S✝¹ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s✝ : Seq β
S✝ S : Seq (Seq1 α)
a : α
s : Seq α
⊢ ∃ s_1 S_1,
    append (Seq.map f s) (Seq.map f (Seq.join S)) = append s_1 (Seq.map f (Seq.join S_1)) ∧
      append (Seq.map f s)
          (Seq.join
            (Seq.map
              (fun x =>
                match x with
                | (a, s) => (f a, Seq.map f s))
              S)) =
        append s_1
          (Seq.join
            (Seq.map
              (fun x =>
                match x with
                | (a, s) => (f a, Seq.map f s))
              S_1))
[PROOFSTEP]
exact ⟨_, _, rfl, rfl⟩
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s : Seq β
S : Seq (Seq1 α)
⊢ β →
    ∀ (s : Seq β),
      ∃ s_1 S_1,
        append s (Seq.map f (Seq.join S)) = append s_1 (Seq.map f (Seq.join S_1)) ∧
          append s (Seq.join (Seq.map (map f) S)) = append s_1 (Seq.join (Seq.map (map f) S_1))
[PROOFSTEP]
intro _ s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
S✝ : Seq (Seq1 α)
s1 s2 : Seq β
h : ∃ s S, s1 = append s (Seq.map f (Seq.join S)) ∧ s2 = append s (Seq.join (Seq.map (map f) S))
s✝ : Seq β
S : Seq (Seq1 α)
x✝ : β
s : Seq β
⊢ ∃ s_1 S_1,
    append s (Seq.map f (Seq.join S)) = append s_1 (Seq.map f (Seq.join S_1)) ∧
      append s (Seq.join (Seq.map (map f) S)) = append s_1 (Seq.join (Seq.map (map f) S_1))
[PROOFSTEP]
refine' ⟨s, S, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ ∃ s S_1,
    Seq.map f (Seq.join S) = append s (Seq.map f (Seq.join S_1)) ∧
      Seq.join (Seq.map (map f) S) = append s (Seq.join (Seq.map (map f) S_1))
[PROOFSTEP]
refine' ⟨nil, S, _, _⟩
[GOAL]
case r.refine'_1
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.map f (Seq.join S) = append nil (Seq.map f (Seq.join S))
[PROOFSTEP]
simp
[GOAL]
case r.refine'_2
α : Type u
β : Type v
γ : Type w
f : α → β
S : Seq (Seq1 α)
⊢ Seq.join (Seq.map (map f) S) = append nil (Seq.join (Seq.map (map f) S))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, s), S)) = join (map (map f) ((a, s), S))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, nil), S)) = join (map (map f) ((a, nil), S))
[PROOFSTEP]
intros
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ ∀ (x : α) (s : Seq α), map f (join ((a, Seq.cons x s), S)) = join (map (map f) ((a, Seq.cons x s), S))
[PROOFSTEP]
intros
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
⊢ map f (join ((a, nil), S)) = join (map (map f) ((a, nil), S))
[PROOFSTEP]
simp [map]
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
f : α → β
a : α
s : Seq α
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
⊢ map f (join ((a, Seq.cons x✝ s✝), S)) = join (map (map f) ((a, Seq.cons x✝ s✝), S))
[PROOFSTEP]
simp [map]
[GOAL]
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.join (Seq.join SS) = Seq.join (Seq.map join SS)
[PROOFSTEP]
apply
  Seq.eq_of_bisim fun s1 s2 =>
    ∃ s SS, s1 = Seq.append s (Seq.join (Seq.join SS)) ∧ s2 = Seq.append s (Seq.join (Seq.map join SS))
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.IsBisimulation fun s1 s2 =>
    ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
[PROOFSTEP]
intro s1 s2 h
[GOAL]
case bisim
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
⊢ BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
    (destruct s1) (destruct s2)
[PROOFSTEP]
exact
  match s1, s2, h with
  | _, _, ⟨s, SS, rfl, rfl⟩ => by
    apply recOn s <;> simp
    · apply recOn SS <;> simp
      · intro S SS
        cases' S with s S; cases' s with x s; simp [map]
        apply recOn s <;> simp
        · exact ⟨_, _, rfl, rfl⟩
        · intro x s
          refine' ⟨Seq.cons x (append s (Seq.join S)), SS, _, _⟩ <;> simp
    · intro _ s
      exact ⟨s, SS, rfl, rfl⟩
[GOAL]
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
    (destruct (append s (Seq.join (Seq.join SS)))) (destruct (append s (Seq.join (Seq.map join SS))))
[PROOFSTEP]
apply recOn s
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
    (destruct (append nil (Seq.join (Seq.join SS)))) (destruct (append nil (Seq.join (Seq.map join SS))))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ ∀ (x : α) (s : Seq α),
    BisimO (fun s1 s2 => ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS)))
      (destruct (append (Seq.cons x s) (Seq.join (Seq.join SS))))
      (destruct (append (Seq.cons x s) (Seq.join (Seq.map join SS))))
[PROOFSTEP]
simp
[GOAL]
case h1
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ match destruct (Seq.join (Seq.join SS)), destruct (Seq.join (Seq.map join SS)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
apply recOn SS
[GOAL]
case h1.h1
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ match destruct (Seq.join (Seq.join nil)), destruct (Seq.join (Seq.map join nil)) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ ∀ (x : Seq1 (Seq1 α)) (s : Seq (Seq1 (Seq1 α))),
    match destruct (Seq.join (Seq.join (Seq.cons x s))), destruct (Seq.join (Seq.map join (Seq.cons x s))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
    | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ ∀ (x : Seq1 (Seq1 α)) (s : Seq (Seq1 (Seq1 α))),
    match destruct (Seq.join (Seq.join (Seq.cons x s))), destruct (Seq.join (Seq.cons (join x) (Seq.map join s))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
    | x, x_1 => False
[PROOFSTEP]
intro S SS
[GOAL]
case h1.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS✝ : Seq (Seq1 (Seq1 α))
S : Seq1 (Seq1 α)
SS : Seq (Seq1 (Seq1 α))
⊢ match destruct (Seq.join (Seq.join (Seq.cons S SS))), destruct (Seq.join (Seq.cons (join S) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
cases' S with s S
[GOAL]
case h1.h2.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
s : Seq1 α
S : Seq (Seq1 α)
⊢ match destruct (Seq.join (Seq.join (Seq.cons (s, S) SS))),
    destruct (Seq.join (Seq.cons (join (s, S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
cases' s with x s
[GOAL]
case h1.h2.mk.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ match destruct (Seq.join (Seq.join (Seq.cons ((x, s), S) SS))),
    destruct (Seq.join (Seq.cons (join ((x, s), S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
simp [map]
[GOAL]
case h1.h2.mk.mk
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ match some (x, append s (append (Seq.join S) (Seq.join (Seq.join SS)))),
    destruct (Seq.join (Seq.cons (join ((x, s), S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
apply recOn s
[GOAL]
case h1.h2.mk.mk.h1
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ match some (x, append nil (append (Seq.join S) (Seq.join (Seq.join SS)))),
    destruct (Seq.join (Seq.cons (join ((x, nil), S)) (Seq.map join SS))) with
  | none, none => True
  | some (a, s), some (a', s') =>
    a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
  | x, x_1 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2.mk.mk.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ ∀ (x_1 : α) (s : Seq α),
    match some (x, append (Seq.cons x_1 s) (append (Seq.join S) (Seq.join (Seq.join SS)))),
      destruct (Seq.join (Seq.cons (join ((x, Seq.cons x_1 s), S)) (Seq.map join SS))) with
    | none, none => True
    | some (a, s), some (a', s') =>
      a = a' ∧ ∃ s_1 SS, s = append s_1 (Seq.join (Seq.join SS)) ∧ s' = append s_1 (Seq.join (Seq.map join SS))
    | x, x_2 => False
[PROOFSTEP]
simp
[GOAL]
case h1.h2.mk.mk.h1
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ ∃ s SS_1,
    append (Seq.join S) (Seq.join (Seq.join SS)) = append s (Seq.join (Seq.join SS_1)) ∧
      append (Seq.join S) (Seq.join (Seq.map join SS)) = append s (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
exact ⟨_, _, rfl, rfl⟩
[GOAL]
case h1.h2.mk.mk.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x : α
s : Seq α
⊢ ∀ (x : α) (s : Seq α),
    ∃ s_1 SS_1,
      Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.join SS)))) = append s_1 (Seq.join (Seq.join SS_1)) ∧
        Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.map join SS)))) =
          append s_1 (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
intro x s
[GOAL]
case h1.h2.mk.mk.h2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝¹ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
x : α
s : Seq α
⊢ ∃ s_1 SS_1,
    Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.join SS)))) = append s_1 (Seq.join (Seq.join SS_1)) ∧
      Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.map join SS)))) =
        append s_1 (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
refine' ⟨Seq.cons x (append s (Seq.join S)), SS, _, _⟩
[GOAL]
case h1.h2.mk.mk.h2.refine'_1
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝¹ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
x : α
s : Seq α
⊢ Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.join SS)))) =
    append (Seq.cons x (append s (Seq.join S))) (Seq.join (Seq.join SS))
[PROOFSTEP]
simp
[GOAL]
case h1.h2.mk.mk.h2.refine'_2
α : Type u
β : Type v
γ : Type w
SS✝¹ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝¹ : Seq α
SS✝ SS : Seq (Seq1 (Seq1 α))
S : Seq (Seq1 α)
x✝ : α
s✝ : Seq α
x : α
s : Seq α
⊢ Seq.cons x (append s (append (Seq.join S) (Seq.join (Seq.map join SS)))) =
    append (Seq.cons x (append s (Seq.join S))) (Seq.join (Seq.map join SS))
[PROOFSTEP]
simp
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s : Seq α
SS : Seq (Seq1 (Seq1 α))
⊢ α →
    ∀ (s : Seq α),
      ∃ s_1 SS_1,
        append s (Seq.join (Seq.join SS)) = append s_1 (Seq.join (Seq.join SS_1)) ∧
          append s (Seq.join (Seq.map join SS)) = append s_1 (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
intro _ s
[GOAL]
case h2
α : Type u
β : Type v
γ : Type w
SS✝ : Seq (Seq1 (Seq1 α))
s1 s2 : Seq α
h : ∃ s SS, s1 = append s (Seq.join (Seq.join SS)) ∧ s2 = append s (Seq.join (Seq.map join SS))
s✝ : Seq α
SS : Seq (Seq1 (Seq1 α))
x✝ : α
s : Seq α
⊢ ∃ s_1 SS_1,
    append s (Seq.join (Seq.join SS)) = append s_1 (Seq.join (Seq.join SS_1)) ∧
      append s (Seq.join (Seq.map join SS)) = append s_1 (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
exact ⟨s, SS, rfl, rfl⟩
[GOAL]
case r
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ ∃ s SS_1,
    Seq.join (Seq.join SS) = append s (Seq.join (Seq.join SS_1)) ∧
      Seq.join (Seq.map join SS) = append s (Seq.join (Seq.map join SS_1))
[PROOFSTEP]
refine' ⟨nil, SS, _, _⟩
[GOAL]
case r.refine'_1
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.join (Seq.join SS) = append nil (Seq.join (Seq.join SS))
[PROOFSTEP]
simp
[GOAL]
case r.refine'_2
α : Type u
β : Type v
γ : Type w
SS : Seq (Seq1 (Seq1 α))
⊢ Seq.join (Seq.map join SS) = append nil (Seq.join (Seq.map join SS))
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
s : Seq1 α
f : α → Seq1 β
g : β → Seq1 γ
⊢ bind (bind s f) g = bind s fun x => bind (f x) g
[PROOFSTEP]
cases' s with a s
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
⊢ bind (bind (a, s) f) g = bind (a, s) fun x => bind (f x) g
[PROOFSTEP]
simp only [bind, map_pair, map_join]
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
⊢ join (join (map g (f a), Seq.map (map g) (Seq.map f s))) =
    join (join (map g (f a)), Seq.map (fun x => join (map g (f x))) s)
[PROOFSTEP]
rw [← map_comp]
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
⊢ join (join (map g (f a), Seq.map (map g ∘ f) s)) = join (join (map g (f a)), Seq.map (fun x => join (map g (f x))) s)
[PROOFSTEP]
simp only [show (fun x => join (map g (f x))) = join ∘ (map g ∘ f) from rfl]
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
⊢ join (join (map g (f a), Seq.map (map g ∘ f) s)) = join (join (map g (f a)), Seq.map (join ∘ map g ∘ f) s)
[PROOFSTEP]
rw [map_comp _ join]
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
⊢ join (join (map g (f a), Seq.map (map g ∘ f) s)) = join (join (map g (f a)), Seq.map join (Seq.map (map g ∘ f) s))
[PROOFSTEP]
generalize Seq.map (map g ∘ f) s = SS
[GOAL]
case mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
⊢ join (join (map g (f a), SS)) = join (join (map g (f a)), Seq.map join SS)
[PROOFSTEP]
rcases map g (f a) with
  ⟨⟨a, s⟩, S⟩
    -- Porting note: Instead of `apply recOn s <;> intros`, `induction'` are used to
      --   give names to variables.
[GOAL]
case mk.mk.mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s✝ : Seq α
SS : Seq (Seq1 (Seq1 γ))
S : Seq (Seq1 γ)
a : γ
s : Seq γ
⊢ join (join (((a, s), S), SS)) = join (join ((a, s), S), Seq.map join SS)
[PROOFSTEP]
induction' s using recOn with x s_1
[GOAL]
case mk.mk.mk.h1
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
S : Seq (Seq1 γ)
a : γ
⊢ join (join (((a, nil), S), SS)) = join (join ((a, nil), S), Seq.map join SS)
[PROOFSTEP]
induction' S using recOn with x_1 s_2
[GOAL]
case mk.mk.mk.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
S : Seq (Seq1 γ)
a x : γ
s_1 : Seq γ
⊢ join (join (((a, Seq.cons x s_1), S), SS)) = join (join ((a, Seq.cons x s_1), S), Seq.map join SS)
[PROOFSTEP]
induction' S using recOn with x_1 s_2
[GOAL]
case mk.mk.mk.h1.h1
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
⊢ join (join (((a, nil), nil), SS)) = join (join ((a, nil), nil), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h1.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
x_1 : Seq1 γ
s_2 : Seq (Seq1 γ)
⊢ join (join (((a, nil), Seq.cons x_1 s_2), SS)) = join (join ((a, nil), Seq.cons x_1 s_2), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h2.h1
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a x : γ
s_1 : Seq γ
⊢ join (join (((a, Seq.cons x s_1), nil), SS)) = join (join ((a, Seq.cons x s_1), nil), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h2.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a x : γ
s_1 : Seq γ
x_1 : Seq1 γ
s_2 : Seq (Seq1 γ)
⊢ join (join (((a, Seq.cons x s_1), Seq.cons x_1 s_2), SS)) =
    join (join ((a, Seq.cons x s_1), Seq.cons x_1 s_2), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h1.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
x_1 : Seq1 γ
s_2 : Seq (Seq1 γ)
⊢ (a, Seq.join (Seq.cons x_1 (append s_2 (Seq.join SS)))) = join ((a, Seq.join (Seq.cons x_1 s_2)), Seq.map join SS)
[PROOFSTEP]
cases' x_1 with x t
[GOAL]
case mk.mk.mk.h1.h2.mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
s_2 : Seq (Seq1 γ)
x : γ
t : Seq γ
⊢ (a, Seq.join (Seq.cons (x, t) (append s_2 (Seq.join SS)))) =
    join ((a, Seq.join (Seq.cons (x, t) s_2)), Seq.map join SS)
[PROOFSTEP]
apply recOn t
[GOAL]
case mk.mk.mk.h1.h2.mk.h1
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
s_2 : Seq (Seq1 γ)
x : γ
t : Seq γ
⊢ (a, Seq.join (Seq.cons (x, nil) (append s_2 (Seq.join SS)))) =
    join ((a, Seq.join (Seq.cons (x, nil) s_2)), Seq.map join SS)
[PROOFSTEP]
intros
[GOAL]
case mk.mk.mk.h1.h2.mk.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
s_2 : Seq (Seq1 γ)
x : γ
t : Seq γ
⊢ ∀ (x_1 : γ) (s : Seq γ),
    (a, Seq.join (Seq.cons (x, Seq.cons x_1 s) (append s_2 (Seq.join SS)))) =
      join ((a, Seq.join (Seq.cons (x, Seq.cons x_1 s) s_2)), Seq.map join SS)
[PROOFSTEP]
intros
[GOAL]
case mk.mk.mk.h1.h2.mk.h1
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
s_2 : Seq (Seq1 γ)
x : γ
t : Seq γ
⊢ (a, Seq.join (Seq.cons (x, nil) (append s_2 (Seq.join SS)))) =
    join ((a, Seq.join (Seq.cons (x, nil) s_2)), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h1.h2.mk.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a : γ
s_2 : Seq (Seq1 γ)
x : γ
t : Seq γ
x✝ : γ
s✝ : Seq γ
⊢ (a, Seq.join (Seq.cons (x, Seq.cons x✝ s✝) (append s_2 (Seq.join SS)))) =
    join ((a, Seq.join (Seq.cons (x, Seq.cons x✝ s✝) s_2)), Seq.map join SS)
[PROOFSTEP]
simp
[GOAL]
case mk.mk.mk.h2.h2
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a x : γ
s_1 : Seq γ
x_1 : Seq1 γ
s_2 : Seq (Seq1 γ)
⊢ (a, Seq.cons x (append s_1 (Seq.join (Seq.cons x_1 (append s_2 (Seq.join SS)))))) =
    (a, Seq.cons x (append s_1 (append (Seq.join (Seq.cons x_1 s_2)) (Seq.join (Seq.map join SS)))))
[PROOFSTEP]
cases' x_1 with y t
[GOAL]
case mk.mk.mk.h2.h2.mk
α : Type u
β : Type v
γ : Type w
f : α → Seq1 β
g : β → Seq1 γ
a✝ : α
s : Seq α
SS : Seq (Seq1 (Seq1 γ))
a x : γ
s_1 : Seq γ
s_2 : Seq (Seq1 γ)
y : γ
t : Seq γ
⊢ (a, Seq.cons x (append s_1 (Seq.join (Seq.cons (y, t) (append s_2 (Seq.join SS)))))) =
    (a, Seq.cons x (append s_1 (append (Seq.join (Seq.cons (y, t) s_2)) (Seq.join (Seq.map join SS)))))
[PROOFSTEP]
simp
