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.