(* This file is distributed under the terms of the MIT License, also known as the X11 Licence.  A copy of this license is in the README file that accompanied the original distribution of this file.  Based on code written by: Brian Aydemir Aaron Bohannon Arthur Charg\'eraud  With contributions from: Edsko de Vries: uniq_reorder_1, uniq_reorder_2, binds_In_inv *)
(** remove printing ~ *)
(** A library for association lists, i.e., lists of pairs *)
Open Scope string_scope.
(* *********************************************************************** *)
(** * Implementation *)
(** We implement association lists as lists of key-value pairs.  We use [eq] as the equality on both keys and values.  This is evident primarily in the definitions of [binds] and [maps].  (Implementation note: We can generalize the implementation to arbitrary equivalence relations.  For now, we have chosen not to, in order to keep the implementation simple and to optimize for what we expect is the common case.)  Note that our library has an implicit convention for the "normal form" of an association list.  This normal form requires that a list be built only from [nil] (the empty list), [one] (the singleton list), and [app] (concatenation).  Additionally, concatenations should be associated to the right and the list should not contain any [nil] terms, unless it is the empty list itself.  This allows association lists to be written in a slightly more uniform manner when compared to using both [cons] and [app] to build them.  The downsides are that Coq's [simpl] tactic will simplify instances of [one] down to [cons] and that there are instances in which one needs to write association lists that are not in normal form (e.g., some concatenations will need to be associated to the left).  The [simpl_alist] and [rewrite_alist] tactics below are designed to minimize the impact of these downsides.  A [Strategy] declaration can be used to prevent Coq's tactics from simplifying [one], if one so desires. *)
(* Implementation note (BEA, XXX): Very little support for - Inversion on association lists when [one] is [opaque]. - No real support for [get]. - No real support for [maps]. - No support for permutations. *)
Module Make
(X : UsualDecidableType)
(KeySet : FSetInterface.WSfun X).
(* SCW: Make an instance of EqDef_eq for X so that we can use the "==" in [get] below. *)
Instance EqDec_of_X : @EqDec X.t eq eq_equivalence.

Lemma binds_app_uniq_iff :
uniq (E ++ F) ->
(binds x a (E ++ F) <->
(binds x a E /\ ~ In x (dom F)) \/
(binds x a F /\ ~ In x (dom E))).