File: Mathlib/Data/Seq/Seq.lean

full_name: Stream'.IsSeq
code: /-- A stream `s : Option α` is a sequence if `s.get n = none` implies `s.get (n + 1) = none`.
-/
def IsSeq {α : Type u} (s : Stream' (Option α)) : Prop 
goal: Prop

full_name: Stream'.Seq
code: /-- `Seq α` is the type of possibly infinite lists (referred here as sequences).
  It is encoded as an infinite stream of options such that if `f n = none`, then
  `f m = none` for all `m ≥ n`. -/
def Seq (α : Type u) : Type u 
goal: Type u

full_name: Stream'.Seq1
code: /-- `Seq1 α` is the type of nonempty sequences. -/
def Seq1 (α) 
goal: Type u_1

full_name: Stream'.Seq.nil
code: /-- The empty sequence -/
def nil : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.instInhabited
code: instance : Inhabited (Seq α) 
goal: Inhabited (Stream'.Seq α)

full_name: Stream'.Seq.cons
code: /-- Prepend an element to a sequence -/
def cons (a : α) (s : Seq α) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.val_cons
code: @[simp]
theorem val_cons (s : Seq α) (x : α) : (cons x s).val = some x::s.val 
goal: ↑(Stream'.Seq.cons x s) = Stream'.cons (some x) ↑s

full_name: Stream'.Seq.get?
code: /-- Get the nth element of a sequence (if it exists) -/
def get? : Seq α → ℕ → Option α 
goal: Stream'.Seq α → ℕ → Option α

full_name: Stream'.Seq.get?_mk
code: @[simp]
theorem get?_mk (f hf) : @get? α ⟨f, hf⟩ = f 
goal: Stream'.Seq.get? ⟨f, hf⟩ = f

full_name: Stream'.Seq.get?_nil
code: @[simp]
theorem get?_nil (n : ℕ) : (@nil α).get? n = none 
goal: Stream'.Seq.nil.get? n = none

full_name: Stream'.Seq.get?_cons_zero
code: @[simp]
theorem get?_cons_zero (a : α) (s : Seq α) : (cons a s).get? 0 = some a 
goal: (Stream'.Seq.cons a s).get? 0 = some a

full_name: Stream'.Seq.get?_cons_succ
code: @[simp]
theorem get?_cons_succ (a : α) (s : Seq α) (n : ℕ) : (cons a s).get? (n + 1) = s.get? n 
goal: (Stream'.Seq.cons a s).get? (n + 1) = s.get? n

full_name: Stream'.Seq.ext
code: @[ext]
protected theorem ext {s t : Seq α} (h : ∀ n : ℕ, s.get? n = t.get? n) : s = t 
goal: s = t

full_name: Stream'.Seq.cons_injective2
code: theorem cons_injective2 : Function.Injective2 (cons : α → Seq α → Seq α) 
goal: Function.Injective2 Stream'.Seq.cons

full_name: Stream'.Seq.cons_left_injective
code: theorem cons_left_injective (s : Seq α) : Function.Injective fun x => cons x s 
goal: Function.Injective fun x => Stream'.Seq.cons x s

full_name: Stream'.Seq.cons_right_injective
code: theorem cons_right_injective (x : α) : Function.Injective (cons x) 
goal: Function.Injective (Stream'.Seq.cons x)

full_name: Stream'.Seq.TerminatedAt
code: /-- A sequence has terminated at position `n` if the value at position `n` equals `none`. -/
def TerminatedAt (s : Seq α) (n : ℕ) : Prop 
goal: Prop

full_name: Stream'.Seq.terminatedAtDecidable
code: /-- It is decidable whether a sequence terminates at a given position. -/
instance terminatedAtDecidable (s : Seq α) (n : ℕ) : Decidable (s.TerminatedAt n) 
goal: Decidable (s.TerminatedAt n)

full_name: Stream'.Seq.Terminates
code: /-- A sequence terminates if there is some position `n` at which it has terminated. -/
def Terminates (s : Seq α) : Prop 
goal: Prop

full_name: Stream'.Seq.not_terminates_iff
code: theorem not_terminates_iff {s : Seq α} : ¬s.Terminates ↔ ∀ n, (s.get? n).isSome 
goal: ¬s.Terminates ↔ ∀ (n : ℕ), (s.get? n).isSome = true

full_name: Stream'.Seq.omap
code: /-- Functorial action of the functor `Option (α × _)` -/
@[simp]
def omap (f : β → γ) : Option (α × β) → Option (α × γ)
  
goal: Option (α × β) → Option (α × γ)

full_name: Stream'.Seq.head
code: /-- Get the first element of a sequence -/
def head (s : Seq α) : Option α 
goal: Option α

full_name: Stream'.Seq.tail
code: /-- Get the tail of a sequence (or `nil` if the sequence is `nil`) -/
def tail (s : Seq α) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.Mem
code: /-- member definition for `Seq`-/
protected def Mem (a : α) (s : Seq α) 
goal: Prop

full_name: Stream'.Seq.instMembership
code: instance : Membership α (Seq α) 
goal: Membership α (Stream'.Seq α)

full_name: Stream'.Seq.le_stable
code: theorem le_stable (s : Seq α) {m n} (h : m ≤ n) : s.get? m = none → s.get? n = none 
goal: s.get? m = none → s.get? n = none

full_name: Stream'.Seq.terminated_stable
code: /-- If a sequence terminated at position `n`, it also terminated at `m ≥ n`. -/
theorem terminated_stable : ∀ (s : Seq α) {m n : ℕ}, m ≤ n → s.TerminatedAt m → s.TerminatedAt n 
goal: m ≤ n → s.TerminatedAt m → s.TerminatedAt n

full_name: Stream'.Seq.ge_stable
code: /-- If `s.get? n = some aₙ` for some value `aₙ`, then there is also some value `aₘ` such
that `s.get? = some aₘ` for `m ≤ n`.
-/
theorem ge_stable (s : Seq α) {aₙ : α} {n m : ℕ} (m_le_n : m ≤ n)
    (s_nth_eq_some : s.get? n = some aₙ) : ∃ aₘ : α, s.get? m = some aₘ 
goal: ∃ aₘ, s.get? m = some aₘ

full_name: Stream'.Seq.not_mem_nil
code: theorem not_mem_nil (a : α) : a ∉ @nil α 
goal: ¬a ∈ Stream'.Seq.nil

full_name: Stream'.Seq.mem_cons
code: theorem mem_cons (a : α) : ∀ s : Seq α, a ∈ cons a s
  
goal: a ∈ Stream'.Seq.cons a s

full_name: Stream'.Seq.mem_cons_of_mem
code: theorem mem_cons_of_mem (y : α) {a : α} : ∀ {s : Seq α}, a ∈ s → a ∈ cons y s
  
goal: a ∈ s → a ∈ Stream'.Seq.cons y s

full_name: Stream'.Seq.eq_or_mem_of_mem_cons
code: theorem eq_or_mem_of_mem_cons {a b : α} : ∀ {s : Seq α}, a ∈ cons b s → a = b ∨ a ∈ s
  
goal: a ∈ Stream'.Seq.cons b s → a = b ∨ a ∈ s

full_name: Stream'.Seq.mem_cons_iff
code: @[simp]
theorem mem_cons_iff {a b : α} {s : Seq α} : a ∈ cons b s ↔ a = b ∨ a ∈ s 
goal: a ∈ Stream'.Seq.cons b s ↔ a = b ∨ a ∈ s

full_name: Stream'.Seq.destruct
code: /-- Destructor for a sequence, resulting in either `none` (for `nil`) or
  `some (a, s)` (for `cons a s`). -/
def destruct (s : Seq α) : Option (Seq1 α) 
goal: Option (Stream'.Seq1 α)

full_name: Stream'.Seq.destruct_eq_nil
code: theorem destruct_eq_nil {s : Seq α} : destruct s = none → s = nil 
goal: s.destruct = none → s = Stream'.Seq.nil

full_name: Stream'.Seq.destruct_eq_cons
code: theorem destruct_eq_cons {s : Seq α} {a s'} : destruct s = some (a, s') → s = cons a s' 
goal: s.destruct = some (a, s') → s = Stream'.Seq.cons a s'

full_name: Stream'.Seq.destruct_nil
code: @[simp]
theorem destruct_nil : destruct (nil : Seq α) = none 
goal: Stream'.Seq.nil.destruct = none

full_name: Stream'.Seq.destruct_cons
code: @[simp]
theorem destruct_cons (a : α) : ∀ s, destruct (cons a s) = some (a, s)
  
goal: (Stream'.Seq.cons a s).destruct = some (a, s)

full_name: Stream'.Seq.head_eq_destruct
code: theorem head_eq_destruct (s : Seq α) : head.{u} s = Prod.fst.{u} <$> destruct.{u} s 
goal: s.head = Prod.fst <$> s.destruct

full_name: Stream'.Seq.head_nil
code: @[simp]
theorem head_nil : head (nil : Seq α) = none 
goal: Stream'.Seq.nil.head = none

full_name: Stream'.Seq.head_cons
code: @[simp]
theorem head_cons (a : α) (s) : head (cons a s) = some a 
goal: (Stream'.Seq.cons a s).head = some a

full_name: Stream'.Seq.tail_nil
code: @[simp]
theorem tail_nil : tail (nil : Seq α) = nil 
goal: Stream'.Seq.nil.tail = Stream'.Seq.nil

full_name: Stream'.Seq.tail_cons
code: @[simp]
theorem tail_cons (a : α) (s) : tail (cons a s) = s 
goal: (Stream'.Seq.cons a s).tail = s

full_name: Stream'.Seq.get?_tail
code: @[simp]
theorem get?_tail (s : Seq α) (n) : get? (tail s) n = get? s (n + 1) 
goal: s.tail.get? n = s.get? (n + 1)

full_name: Stream'.Seq.recOn
code: /-- Recursion principle for sequences, compare with `List.recOn`. -/
def recOn {C : Seq α → Sort v} (s : Seq α) (h1 : C nil) (h2 : ∀ x s, C (cons x s)) :
    C s 
goal: C s

full_name: Stream'.Seq.mem_rec_on
code: theorem mem_rec_on {C : Seq α → Prop} {a s} (M : a ∈ s)
    (h1 : ∀ b s', a = b ∨ C s' → C (cons b s')) : C s 
goal: C s

full_name: Stream'.Seq.Corec.f
code: /-- Corecursor over pairs of `Option` values-/
def Corec.f (f : β → Option (α × β)) : Option β → Option α × Option β
  
goal: Option β → Option α × Option β

full_name: Stream'.Seq.corec
code: /-- Corecursor for `Seq α` as a coinductive type. Iterates `f` to produce new elements
  of the sequence until `none` is obtained. -/
def corec (f : β → Option (α × β)) (b : β) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.corec_eq
code: @[simp]
theorem corec_eq (f : β → Option (α × β)) (b : β) :
    destruct (corec f b) = omap (corec f) (f b) 
goal: (Stream'.Seq.corec f b).destruct = Stream'.Seq.omap (Stream'.Seq.corec f) (f b)

full_name: Stream'.Seq.«_aux_Mathlib_Data_Seq_Seq___macroRules_Stream'_Seq_term_~__1»
code: local infixl:50 " ~ " => R
goal: Lean.Macro

full_name: Stream'.Seq.BisimO
code: /-- Bisimilarity relation over `Option` of `Seq1 α`-/
def BisimO : Option (Seq1 α) → Option (Seq1 α) → Prop
  
goal: Option (Stream'.Seq1 α) → Option (Stream'.Seq1 α) → Prop

full_name: Stream'.Seq.IsBisimulation
code: /-- a relation is bisimilar if it meets the `BisimO` test-/
def IsBisimulation 
goal: Prop

full_name: Stream'.Seq.eq_of_bisim
code: theorem eq_of_bisim (bisim : IsBisimulation R) {s₁ s₂} (r : s₁ ~ s₂) : s₁ = s₂ 
goal: s₁ = s₂

full_name: Stream'.Seq.coinduction
code: theorem coinduction :
    ∀ {s₁ s₂ : Seq α},
      head s₁ = head s₂ →
        (∀ (β : Type u) (fr : Seq α → β), fr s₁ = fr s₂ → fr (tail s₁) = fr (tail s₂)) → s₁ = s₂
  
goal: s₁.head = s₂.head → (∀ (β : Type u) (fr : Stream'.Seq α → β), fr s₁ = fr s₂ → fr s₁.tail = fr s₂.tail) → s₁ = s₂

full_name: Stream'.Seq.coinduction2
code: theorem coinduction2 (s) (f g : Seq α → Seq β)
    (H :
      ∀ s,
        BisimO (fun s1 s2 : Seq β => ∃ s : Seq α, s1 = f s ∧ s2 = g s) (destruct (f s))
          (destruct (g s))) :
    f s = g s 
goal: f s = g s

full_name: Stream'.Seq.ofList
code: /-- Embed a list as a sequence -/
@[coe]
def ofList (l : List α) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.coeList
code: instance coeList : Coe (List α) (Seq α) 
goal: Coe (List α) (Stream'.Seq α)

full_name: Stream'.Seq.ofList_nil
code: @[simp]
theorem ofList_nil : ofList [] = (nil : Seq α) 
goal: ↑[] = Stream'.Seq.nil

full_name: Stream'.Seq.ofList_get
code: @[simp]
theorem ofList_get (l : List α) (n : ℕ) : (ofList l).get? n = l.get? n 
goal: (↑l).get? n = l.get? n

full_name: Stream'.Seq.ofList_cons
code: @[simp]
theorem ofList_cons (a : α) (l : List α) : ofList (a::l) = cons a (ofList l) 
goal: ↑(a :: l) = Stream'.Seq.cons a ↑l

full_name: Stream'.Seq.ofStream
code: /-- Embed an infinite stream as a sequence -/
@[coe]
def ofStream (s : Stream' α) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.coeStream
code: instance coeStream : Coe (Stream' α) (Seq α) 
goal: Coe (Stream' α) (Stream'.Seq α)

full_name: Stream'.Seq.ofLazyList
code: /-- Embed a `LazyList α` as a sequence. Note that even though this
  is non-meta, it will produce infinite sequences if used with
  cyclic `LazyList`s created by meta constructions. -/
@[deprecated (since := "2024-07-22")]
def ofLazyList : LazyList α → Seq α 
goal: LazyList α → Stream'.Seq α

full_name: Stream'.Seq.coeLazyList
code: @[deprecated (since := "2024-07-22")]
instance coeLazyList : Coe (LazyList α) (Seq α) 
goal: Coe (LazyList α) (Stream'.Seq α)

full_name: Stream'.Seq.toLazyList
code: /-- Translate a sequence into a `LazyList`. Since `LazyList` and `List`
  are isomorphic as non-meta types, this function is necessarily meta. -/
@[deprecated (since := "2024-07-22")]
unsafe def toLazyList : Seq α → LazyList α
  
goal: Stream'.Seq α → LazyList α

full_name: Stream'.Seq.forceToList
code: /-- Translate a sequence to a list. This function will run forever if
  run on an infinite sequence. -/
unsafe def forceToList : Seq α → List α
  
goal: Stream'.Seq α → List α

full_name: Stream'.Seq.nats
code: /-- The sequence of natural numbers some 0, some 1, ... -/
def nats : Seq ℕ 
goal: Stream'.Seq ℕ

full_name: Stream'.Seq.nats_get?
code: @[simp]
theorem nats_get? (n : ℕ) : nats.get? n = some n 
goal: Stream'.Seq.nats.get? n = some n

full_name: Stream'.Seq.append
code: /-- Append two sequences. If `s₁` is infinite, then `s₁ ++ s₂ = s₁`,
  otherwise it puts `s₂` at the location of the `nil` in `s₁`. -/
def append (s₁ s₂ : Seq α) : Seq α 
goal: Stream'.Seq α

full_name: Stream'.Seq.map
code: /-- Map a function over a sequence. -/
def map (f : α → β) : Seq α → Seq β
  
goal: Stream'.Seq α → Stream'.Seq β

full_name: Stream'.Seq.join
code: /-- Flatten a sequence of sequences. (It is required that the
  sequences be nonempty to ensure productivity; in the case
  of an infinite sequence of `nil`, the first element is never
  generated.) -/
def join : Seq (Seq1 α) → Seq α 
goal: Stream'.Seq (Stream'.Seq1 α) → Stream'.Seq α

full_name: Stream'.Seq.drop
code: /-- Remove the first `n` elements from the sequence. -/
def drop (s : Seq α) : ℕ → Seq α
  
goal: ℕ → Stream'.Seq α

full_name: Stream'.Seq.take
code: /-- Take the first `n` elements of the sequence (producing a list) -/
def take : ℕ → Seq α → List α
  
goal: ℕ → Stream'.Seq α → List α

full_name: Stream'.Seq.splitAt
code: /-- Split a sequence at `n`, producing a finite initial segment
  and an infinite tail. -/
def splitAt : ℕ → Seq α → List α × Seq α
  
goal: ℕ → Stream'.Seq α → List α × Stream'.Seq α

full_name: Stream'.Seq.zipWith
code: /-- Combine two sequences with a function -/
def zipWith (f : α → β → γ) (s₁ : Seq α) (s₂ : Seq β) : Seq γ 
goal: Stream'.Seq γ

full_name: Stream'.Seq.get?_zipWith
code: @[simp]
theorem get?_zipWith (f : α → β → γ) (s s' n) :
    (zipWith f s s').get? n = Option.map₂ f (s.get? n) (s'.get? n) 
goal: (Stream'.Seq.zipWith f s s').get? n = Option.map₂ f (s.get? n) (s'.get? n)

full_name: Stream'.Seq.zip
code: /-- Pair two sequences into a sequence of pairs -/
def zip : Seq α → Seq β → Seq (α × β) 
goal: Stream'.Seq α → Stream'.Seq β → Stream'.Seq (α × β)

full_name: Stream'.Seq.get?_zip
code: theorem get?_zip (s : Seq α) (t : Seq β) (n : ℕ) :
    get? (zip s t) n = Option.map₂ Prod.mk (get? s n) (get? t n) 
goal: (s.zip t).get? n = Option.map₂ Prod.mk (s.get? n) (t.get? n)

full_name: Stream'.Seq.unzip
code: /-- Separate a sequence of pairs into two sequences -/
def unzip (s : Seq (α × β)) : Seq α × Seq β 
goal: Stream'.Seq α × Stream'.Seq β

full_name: Stream'.Seq.enum
code: /-- Enumerate a sequence by tagging each element with its index. -/
def enum (s : Seq α) : Seq (ℕ × α) 
goal: Stream'.Seq (ℕ × α)

full_name: Stream'.Seq.get?_enum
code: @[simp]
theorem get?_enum (s : Seq α) (n : ℕ) : get? (enum s) n = Option.map (Prod.mk n) (get? s n) 
goal: s.enum.get? n = Option.map (Prod.mk n) (s.get? n)

full_name: Stream'.Seq.enum_nil
code: @[simp]
theorem enum_nil : enum (nil : Seq α) = nil 
goal: Stream'.Seq.nil.enum = Stream'.Seq.nil

full_name: Stream'.Seq.toList
code: /-- Convert a sequence which is known to terminate into a list -/
def toList (s : Seq α) (h : s.Terminates) : List α 
goal: List α

full_name: Stream'.Seq.toStream
code: /-- Convert a sequence which is known not to terminate into a stream -/
def toStream (s : Seq α) (h : ¬s.Terminates) : Stream' α 
goal: Stream' α

full_name: Stream'.Seq.toListOrStream
code: /-- Convert a sequence into either a list or a stream depending on whether
  it is finite or infinite. (Without decidability of the infiniteness predicate,
  this is not constructively possible.) -/
def toListOrStream (s : Seq α) [Decidable s.Terminates] : List α ⊕ Stream' α 
goal: List α ⊕ Stream' α

full_name: Stream'.Seq.nil_append
code: @[simp]
theorem nil_append (s : Seq α) : append nil s = s 
goal: Stream'.Seq.nil.append s = s

full_name: Stream'.Seq.cons_append
code: @[simp]
theorem cons_append (a : α) (s t) : append (cons a s) t = cons a (append s t) 
goal: (Stream'.Seq.cons a s).append t = Stream'.Seq.cons a (s.append t)

full_name: Stream'.Seq.append_nil
code: @[simp]
theorem append_nil (s : Seq α) : append s nil = s 
goal: s.append Stream'.Seq.nil = s

full_name: Stream'.Seq.append_assoc
code: @[simp]
theorem append_assoc (s t u : Seq α) : append (append s t) u = append s (append t u) 
goal: (s.append t).append u = s.append (t.append u)

full_name: Stream'.Seq.map_nil
code: @[simp]
theorem map_nil (f : α → β) : map f nil = nil 
goal: Stream'.Seq.map f Stream'.Seq.nil = Stream'.Seq.nil

full_name: Stream'.Seq.map_cons
code: @[simp]
theorem map_cons (f : α → β) (a) : ∀ s, map f (cons a s) = cons (f a) (map f s)
  
goal: Stream'.Seq.map f (Stream'.Seq.cons a s) = Stream'.Seq.cons (f a) (Stream'.Seq.map f s)

full_name: Stream'.Seq.map_id
code: @[simp]
theorem map_id : ∀ s : Seq α, map id s = s
  
goal: Stream'.Seq.map id s = s

full_name: Stream'.Seq.map_tail
code: @[simp]
theorem map_tail (f : α → β) : ∀ s, map f (tail s) = tail (map f s)
  
goal: Stream'.Seq.map f s.tail = (Stream'.Seq.map f s).tail

full_name: Stream'.Seq.map_comp
code: theorem map_comp (f : α → β) (g : β → γ) : ∀ s : Seq α, map (g ∘ f) s = map g (map f s)
  
goal: Stream'.Seq.map (g ∘ f) s = Stream'.Seq.map g (Stream'.Seq.map f s)

full_name: Stream'.Seq.map_append
code: @[simp]
theorem map_append (f : α → β) (s t) : map f (append s t) = append (map f s) (map f t) 
goal: Stream'.Seq.map f (s.append t) = (Stream'.Seq.map f s).append (Stream'.Seq.map f t)

full_name: Stream'.Seq.map_get?
code: @[simp]
theorem map_get? (f : α → β) : ∀ s n, get? (map f s) n = (get? s n).map f
  
goal: (Stream'.Seq.map f s).get? n = Option.map f (s.get? n)

full_name: Stream'.Seq.instFunctor
code: instance : Functor Seq 
goal: Functor Stream'.Seq

full_name: Stream'.Seq.instLawfulFunctor
code: instance : LawfulFunctor Seq 
goal: LawfulFunctor Stream'.Seq

full_name: Stream'.Seq.join_nil
code: @[simp]
theorem join_nil : join nil = (nil : Seq α) 
goal: Stream'.Seq.nil.join = Stream'.Seq.nil

full_name: Stream'.Seq.join_cons_nil
code: theorem join_cons_nil (a : α) (S) : join (cons (a, nil) S) = cons a (join S) 
goal: (Stream'.Seq.cons (a, Stream'.Seq.nil) S).join = Stream'.Seq.cons a S.join

full_name: Stream'.Seq.join_cons_cons
code: theorem join_cons_cons (a b : α) (s S) :
    join (cons (a, cons b s) S) = cons a (join (cons (b, s) S)) 
goal: (Stream'.Seq.cons (a, Stream'.Seq.cons b s) S).join = Stream'.Seq.cons a (Stream'.Seq.cons (b, s) S).join

full_name: Stream'.Seq.join_cons
code: @[simp]
theorem join_cons (a : α) (s S) : join (cons (a, s) S) = cons a (append s (join S)) 
goal: (Stream'.Seq.cons (a, s) S).join = Stream'.Seq.cons a (s.append S.join)

full_name: Stream'.Seq.join_append
code: @[simp]
theorem join_append (S T : Seq (Seq1 α)) : join (append S T) = append (join S) (join T) 
goal: (S.append T).join = S.join.append T.join

full_name: Stream'.Seq.ofStream_cons
code: @[simp]
theorem ofStream_cons (a : α) (s) : ofStream (a::s) = cons a (ofStream s) 
goal: ↑(Stream'.cons a s) = Stream'.Seq.cons a ↑s

full_name: Stream'.Seq.ofList_append
code: @[simp]
theorem ofList_append (l l' : List α) : ofList (l ++ l') = append (ofList l) (ofList l') 
goal: ↑(l ++ l') = (↑l).append ↑l'

full_name: Stream'.Seq.ofStream_append
code: @[simp]
theorem ofStream_append (l : List α) (s : Stream' α) :
    ofStream (l ++ₛ s) = append (ofList l) (ofStream s) 
goal: ↑(l ++ₛ s) = (↑l).append ↑s

full_name: Stream'.Seq.toList'
code: /-- Convert a sequence into a list, embedded in a computation to allow for
  the possibility of infinite sequences (in which case the computation
  never returns anything). -/
def toList' {α} (s : Seq α) : Computation (List α) 
goal: Computation (List α)

full_name: Stream'.Seq.dropn_add
code: theorem dropn_add (s : Seq α) (m) : ∀ n, drop s (m + n) = drop (drop s m) n
  
goal: s.drop (m + n) = (s.drop m).drop n

full_name: Stream'.Seq.dropn_tail
code: theorem dropn_tail (s : Seq α) (n) : drop (tail s) n = drop s (n + 1) 
goal: s.tail.drop n = s.drop (n + 1)

full_name: Stream'.Seq.head_dropn
code: @[simp]
theorem head_dropn (s : Seq α) (n) : head (drop s n) = get? s n 
goal: (s.drop n).head = s.get? n

full_name: Stream'.Seq.mem_map
code: theorem mem_map (f : α → β) {a : α} : ∀ {s : Seq α}, a ∈ s → f a ∈ map f s
  
goal: a ∈ s → f a ∈ Stream'.Seq.map f s

full_name: Stream'.Seq.exists_of_mem_map
code: theorem exists_of_mem_map {f} {b : β} : ∀ {s : Seq α}, b ∈ map f s → ∃ a, a ∈ s ∧ f a = b 
goal: b ∈ Stream'.Seq.map f s → ∃ a, a ∈ s ∧ f a = b

full_name: Stream'.Seq.of_mem_append
code: theorem of_mem_append {s₁ s₂ : Seq α} {a : α} (h : a ∈ append s₁ s₂) : a ∈ s₁ ∨ a ∈ s₂ 
goal: a ∈ s₁ ∨ a ∈ s₂

full_name: Stream'.Seq.mem_append_left
code: theorem mem_append_left {s₁ s₂ : Seq α} {a : α} (h : a ∈ s₁) : a ∈ append s₁ s₂ 
goal: a ∈ s₁.append s₂

full_name: Stream'.Seq.enum_cons
code: @[simp]
theorem enum_cons (s : Seq α) (x : α) :
    enum (cons x s) = cons (0, x) (map (Prod.map Nat.succ id) (enum s)) 
goal: (Stream'.Seq.cons x s).enum = Stream'.Seq.cons (0, x) (Stream'.Seq.map (Prod.map Nat.succ id) s.enum)

full_name: Stream'.Seq1.toSeq
code: /-- Convert a `Seq1` to a sequence. -/
def toSeq : Seq1 α → Seq α
  
goal: Stream'.Seq1 α → Stream'.Seq α

full_name: Stream'.Seq1.coeSeq
code: instance coeSeq : Coe (Seq1 α) (Seq α) 
goal: Coe (Stream'.Seq1 α) (Stream'.Seq α)

full_name: Stream'.Seq1.map
code: /-- Map a function on a `Seq1` -/
def map (f : α → β) : Seq1 α → Seq1 β
  
goal: Stream'.Seq1 α → Stream'.Seq1 β

full_name: Stream'.Seq1.map_pair
code: theorem map_pair {f : α → β} {a s} : map f (a, s) = (f a, Seq.map f s) 
goal: Stream'.Seq1.map f (a, s) = (f a, Stream'.Seq.map f s)

full_name: Stream'.Seq1.map_id
code: theorem map_id : ∀ s : Seq1 α, map id s = s
  
goal: Stream'.Seq1.map id s = s

full_name: Stream'.Seq1.join
code: /-- Flatten a nonempty sequence of nonempty sequences -/
def join : Seq1 (Seq1 α) → Seq1 α
  
goal: Stream'.Seq1 (Stream'.Seq1 α) → Stream'.Seq1 α

full_name: Stream'.Seq1.join_nil
code: @[simp]
theorem join_nil (a : α) (S) : join ((a, nil), S) = (a, Seq.join S) 
goal: Stream'.Seq1.join ((a, Stream'.Seq.nil), S) = (a, S.join)

full_name: Stream'.Seq1.join_cons
code: @[simp]
theorem join_cons (a b : α) (s S) :
    join ((a, Seq.cons b s), S) = (a, Seq.join (Seq.cons (b, s) S)) 
goal: Stream'.Seq1.join ((a, Stream'.Seq.cons b s), S) = (a, (Stream'.Seq.cons (b, s) S).join)

full_name: Stream'.Seq1.ret
code: /-- The `return` operator for the `Seq1` monad,
  which produces a singleton sequence. -/
def ret (a : α) : Seq1 α 
goal: Stream'.Seq1 α

full_name: Stream'.Seq1.instInhabited
code: instance [Inhabited α] : Inhabited (Seq1 α) 
goal: Inhabited (Stream'.Seq1 α)

full_name: Stream'.Seq1.bind
code: /-- The `bind` operator for the `Seq1` monad,
  which maps `f` on each element of `s` and appends the results together.
  (Not all of `s` may be evaluated, because the first few elements of `s`
  may already produce an infinite result.) -/
def bind (s : Seq1 α) (f : α → Seq1 β) : Seq1 β 
goal: Stream'.Seq1 β

full_name: Stream'.Seq1.join_map_ret
code: @[simp]
theorem join_map_ret (s : Seq α) : Seq.join (Seq.map ret s) = s 
goal: (Stream'.Seq.map Stream'.Seq1.ret s).join = s

full_name: Stream'.Seq1.bind_ret
code: @[simp]
theorem bind_ret (f : α → β) : ∀ s, bind s (ret ∘ f) = map f s
  
goal: s.bind (Stream'.Seq1.ret ∘ f) = Stream'.Seq1.map f s

full_name: Stream'.Seq1.ret_bind
code: @[simp]
theorem ret_bind (a : α) (f : α → Seq1 β) : bind (ret a) f = f a 
goal: (Stream'.Seq1.ret a).bind f = f a

full_name: Stream'.Seq1.map_join'
code: @[simp]
theorem map_join' (f : α → β) (S) : Seq.map f (Seq.join S) = Seq.join (Seq.map (map f) S) 
goal: Stream'.Seq.map f S.join = (Stream'.Seq.map (Stream'.Seq1.map f) S).join

full_name: Stream'.Seq1.map_join
code: @[simp]
theorem map_join (f : α → β) : ∀ S, map f (join S) = join (map (map f) S)
  
goal: Stream'.Seq1.map f S.join = (Stream'.Seq1.map (Stream'.Seq1.map f) S).join

full_name: Stream'.Seq1.join_join
code: @[simp]
theorem join_join (SS : Seq (Seq1 (Seq1 α))) :
    Seq.join (Seq.join SS) = Seq.join (Seq.map join SS) 
goal: SS.join.join = (Stream'.Seq.map Stream'.Seq1.join SS).join

full_name: Stream'.Seq1.bind_assoc
code: @[simp]
theorem bind_assoc (s : Seq1 α) (f : α → Seq1 β) (g : β → Seq1 γ) :
    bind (bind s f) g = bind s fun x : α => bind (f x) g 
goal: (s.bind f).bind g = s.bind fun x => (f x).bind g

full_name: Stream'.Seq1.monad
code: instance monad : Monad Seq1 
goal: Monad Stream'.Seq1

full_name: Stream'.Seq1.lawfulMonad
code: instance lawfulMonad : LawfulMonad Seq1 
goal: LawfulMonad Stream'.Seq1