Program Definition stream_app {A: Type} (h1 h2: stream A): stream A :=
  fun n: nat =>
    match partial_stream_len h1 n return option A with
    | None => h1 n
    | Some m => h2 (n - m)
    end.

(* Specifications: *)
Lemma stream_app_spec1 {A: Type}: forall (h1 h2: stream A) (m: nat), is_at_least_n_stream (S m) h1 -> stream_app h1 h2 m = h1 m.
Lemma stream_app_spec1' {A: Type}: forall (h1 h2: stream A) (m: nat) a, h1 m = Some a -> stream_app h1 h2 m = Some a.
Lemma stream_app_spec2 {A: Type}: forall (h1 h2: stream A) (n m: nat), is_n_stream n h1 -> stream_app h1 h2 (m + n) = h2 m.
Lemma stream_app_empty_stream {A: Type}: forall (h: stream A), stream_app h empty_stream = h.
Lemma stream_app_fstn_skipn {A: Type}: forall (h: stream A) (n: nat), stream_app (fstn_stream n h) (skipn_stream n h) = h.
Lemma stream_map_stream_app {A B: Type}: forall (f: A -> B) (h1 h2: stream A), stream_map f (stream_app h1 h2) = stream_app (stream_map f h1) (stream_map f h2).
Lemma stream_app_fstn_stream {A: Type}: forall (h1 h2: stream A) (n: nat), is_n_stream n h1 -> fstn_stream n (stream_app h1 h2) = h1.
Lemma stream_app_skipn_stream {A: Type}: forall (h1 h2: stream A) (n: nat), is_n_stream n h1 -> skipn_stream n (stream_app h1 h2) = h2.