Definition is_n_stream {A: Type} (n: nat) (h: stream A): Prop :=
  h n = None /\ forall n', n' < n -> h n' <> None.Definition is_fin_stream {A: Type} (h: stream A): Prop :=
  exists n, h n = None.Definition is_inf_stream {A: Type} (h: stream A): Prop :=
  forall n, h n <> None.Definition is_at_least_n_stream {A: Type} (n: nat) (h: stream A): Prop :=
  forall n', n' < n -> h n' <> None.Definition is_at_most_n_stream {A: Type} (n: nat) (h: stream A): Prop :=
  h n = None.Definition is_empty_stream {A: Type}: stream A -> Prop :=
  is_n_stream 0.

(* Specifications: *)
Lemma n_stream_inf_stream_conflict {A: Type}: forall (h: stream A) (n: nat), is_n_stream n h -> is_inf_stream h -> False.
Lemma is_n_stream_pf {A: Type}: forall (h: stream A) (n m: nat), is_n_stream m h -> is_n_stream n h -> n = m.
Lemma at_most_n_stream_Sn {A: Type}: forall (h: stream A) (n: nat), is_at_most_n_stream (S n) h <-> is_at_most_n_stream n h \/ is_n_stream (S n) h.
Lemma at_most_n_stream_0 {A: Type}: forall (h: stream A), is_at_most_n_stream 0 h <-> is_n_stream 0 h.
Lemma at_most_n_stream_spec {A: Type}: forall (h: stream A) (n: nat), is_at_most_n_stream n h <-> exists m, m <= n /\ is_n_stream m h.
Lemma is_fin_stream_spec {A}: forall (h: stream A), is_fin_stream h <-> exists n, is_n_stream n h.
Lemma at_most_n_stream_mono {A: Type}: forall (h: stream A) (n m: nat), n <= m -> is_at_most_n_stream n h -> is_at_most_n_stream m h.
Lemma at_most_n_stream_is_fin_stream {A: Type}: forall (h: stream A) (n: nat), is_at_most_n_stream n h -> is_fin_stream h.
Lemma n_stream_or_inf_stream {A: Type}: forall (h: stream A), (exists n, is_n_stream n h) \/ is_inf_stream h.
Lemma at_least_n_stream_Sn {A: Type}: forall (h: stream A) (n: nat), is_at_least_n_stream (S n) h <-> is_at_least_n_stream n h /\ ~ is_n_stream n h.
Lemma at_least_n_stream_0 {A: Type}: forall (h: stream A), is_at_least_n_stream 0 h <-> True.
Lemma at_least_n_stream_spec {A: Type}: forall (h: stream A) (n: nat), is_at_least_n_stream n h <-> (exists m, m >= n /\ is_n_stream m h) \/ is_inf_stream h.
Lemma is_inf_stream_spec {A}: forall (h: stream A), is_inf_stream h <-> forall n, ~ is_n_stream n h.
Lemma at_least_n_stream_mono {A: Type}: forall (h: stream A) (n m: nat), n <= m -> is_at_least_n_stream m h -> is_at_least_n_stream n h.
Lemma inf_stream_is_at_least_n_stream_is_fin_stream {A: Type}: forall (h: stream A) (n: nat), is_inf_stream h -> is_at_least_n_stream n h.
Lemma at_most_n_stream_or_at_least_Sn_stream {A: Type}: forall (h: stream A) (n: nat), is_at_most_n_stream n h \/ is_at_least_n_stream (S n) h.
Lemma at_most_n_stream_or_at_least_n_stream {A: Type}: forall (h: stream A) (n: nat), is_at_most_n_stream n h \/ is_at_least_n_stream n h.