(* ---------------------------------------------------------------------------- *)

(* Extending an environment with a list of bindings found in a pattern. *)

(* Note that we cannot define the concatenation of two environments, because
   we view environments as total functions, so we do not have precise control
   over their domain. Only a list has finite domain. *)

(* Concatenation is just an iterated version of [insert 0]. *)

Fixpoint concat (A : Type) (e1 : env A) (e2 : list A) : env A :=
  match e2 with
  | nil =>
      e1
  | cons a e2 =>
      concat (insert 0 a e1) e2
  end.

(* Specifications: *)
Lemma omega_hint_1: forall n, n <= (n + 1) - 1.
Lemma length_concat: forall A (e2 : list A) (e1 : env A) n1 n, length e1 <= n1 -> n1 + length e2 = n -> length (concat e1 e2) <= n.
Lemma agree_concat: forall A (e : list A) (e1 e2 : env A) k n, agree e1 e2 k -> k + length e = n -> agree (concat e1 e) (concat e2 e) n.
Lemma insert_concat: forall (A : Type) n x nx (o : option A) e1 e2, length e2 = n -> n + x = nx -> raw_insert nx o (concat e1 e2) = concat (raw_insert x o e1) e2.