End UniqProperties.
Hint Rewrite uniq_app uniq_map : rewr_uniq.
(* ********************************************************************* *)
(** ** The [solve_uniq] tactic *)
(** This tactic attempts to solve goals about [uniq].  Given its definition, it's likely to work only when the hypotheses in the goal already contain all the relevant [uniq] propositions. Thus, the tactic may not be generally useful.  It is useful, however, for proving facts about [uniq] such as the ones below.  Implementation note: The second [simpl_asnlist] in the definition is because of [disjoint_one_{l,r}].  The "[|| fail]" at the end is so that in the case of failure, the error message reported to the user is not the one from [fsetdec]. *)
Ltac solve_uniq :=
try trivial;
simpl_asnlist in *;
autorewrite with rewr_uniq in *;
simpl_asnlist in *;
intuition (
auto using uniq_nil, uniq_one_1 ||
(rewrite -> disjoint_sym; auto) ||
(unfold disjoint in *; fsetdec))
|| fail.
(* ********************************************************************* *)
(** ** Facts about [uniq] *)
Section UniqDerived.
Variables A B : Set.
Variables x y : atom.
Variables a b : A.
Variables E F G : list (asn A B).

(* Specifications: *)
Lemma uniq_cons_3 :
uniq E ->
x `notin` dom E ->
uniq ((VarAsn B x a) :: E).
Lemma binds_one_2 :
binds x a (one (VarAsn B y b)) ->
a = b.
Lemma binds_one_iff :
binds x a (one (VarAsn B y b)) <-> x = y /\ a = b.
Lemma binds_cons_1 :
binds x a ((VarAsn B y b) :: E) ->
(x = y /\ a = b) \/ binds x a E.
Lemma binds_app_1 :
binds x a E ->
binds x a (E ++ F).
Lemma binds_app :
binds x a (E ++ F) <-> binds x a E \/ binds x a F.