Definition unify_list
  (s : list (variable * value)) (lv : list value) (lp : list pattern) :
  option (variable -> value) :=
  option_map (assoc_default (variable_beq variable_eq_dec) value_default) (unify_list_aux s lv lp).

(* Specifications: *)
Lemma unify_list_unify_unify_list : forall s s' v lv p lp, unify_list_aux s (v :: lv) (p :: lp) = Some s' -> exists s'', unify s v p = Some s'' /\ unify_list_aux s'' lv lp = Some s'.
Lemma unify_list_length : forall s s' lv lp, unify_list_aux s lv lp = Some s' -> length lv = length lp.
Lemma unify_cons_eq_unify_list : forall s s' c lv c' lp', unify s (c_capply c lv) (p_capply c' lp') = Some s' -> c = c' /\ unify_list_aux s lv lp' = Some s'.
Lemma unify_list_aux_extension lv lp s s': unify_list_aux s lv lp = Some s' -> exists s'', s' = s'' ++ s /\ forall x, assoc (variable_beq variable_eq_dec) x s <> None -> assoc (variable_beq variable_eq_dec) x s'' = None.
Lemma unify_all_vars_defined : forall (s s': list (variable * value)) (v: value) (p: pattern), unify s v p = Some s' -> forall x, In x (vars_of_pattern p) -> assoc (variable_beq variable_eq_dec) x s' <> None.
Lemma eq_psubst_consistent_assoc_extension : forall s s' p, (forall x, assoc (variable_beq variable_eq_dec) x s <> None -> assoc (variable_beq variable_eq_dec) x s' = None) -> (forall x, In x (vars_of_pattern p) -> assoc (variable_beq variable_eq_dec) x s <> None) -> psubst (assoc_default (variable_beq variable_eq_dec) value_default (s' ++ s)) p = psubst (assoc_default (variable_beq variable_eq_dec) value_default s) p.
Lemma unify_sound : forall (s s': list (variable * value)) (v: value) (p: pattern), unify s v p = Some s' -> psubst (assoc_default (variable_beq variable_eq_dec) value_default s') p = v.
Lemma psubst_app p v (s s' : list (variable * value)) : (forall x : variable, assoc (variable_beq variable_eq_dec) x s <> None -> assoc (variable_beq variable_eq_dec) x s' = None) -> (forall x, In x (vars_of_pattern p) -> assoc (variable_beq variable_eq_dec) x s <> None) -> psubst (assoc_default (variable_beq variable_eq_dec) value_default s ) p = v -> psubst (assoc_default (variable_beq variable_eq_dec) value_default (s' ++ s)) p = v.
Lemma unify_list_sound : forall (lp : list pattern) (lv : list value) (s : variable -> value), unify_list [] lv lp = Some s -> map (psubst s) lp = lv.