(*************************************************************************)
(**                                                                      *)
(** * Typing: preservation and progress                                  *)
(**                                                                      *)
(*************************************************************************)
(*************************************************************************)
(** * Typing contexts *)
(*************************************************************************)
(** We represent contexts as association lists (lists of pairs of keys and values) whose keys are [atom]s.   *)
(** For STLC, contexts bind [atom]s to [typ]s.  We define an abbreviation [ctx] for the type of these contexts.  Lists are defined in Coq's standard library, with the constructors [nil] and [cons].  The list library includes the [::] notation for cons as well as standard list operations such as append, map, and fold. The infix operation "++" is list append.  The Metatheory library extends this reasoning by instantiating the AssocList library to provide support for association lists whose keys are [atom]s.  Everything in this library is polymorphic over the type of objects bound in the context.  Look in AssocList for additional details about the functions and predicates that we mention below.  *)
(** Context equality *)
(** When reasoning about contexts, we often need to talk about bindings in the "middle" of an context. Therefore, it is common for lemmas and definitions to use list append in their statements. Unfortunately, list append is associative, so two Coq expressions may denote the same context even though they are not equal.  The tactic [simpl_env] reassociates all concatenations of contexts to the right.  *)

Lemma append_assoc_demo : forall (E0 E1 E2 E3:ctx),
E0 ++ (E1 ++ E2) ++ E3 = E0 ++ E1 ++ E2 ++ E3.