Definition one (C : Set) (item : C) : list C := cons item nil.Inductive asn (A:Set) (B:Set) : Set :=
      | VarAsn : atom -> A -> asn A B
      | AltAsn : B         -> asn A B
    .Inductive asn (A:Set) (B:Set) : Set :=
      | VarAsn : atom -> A -> asn A B
      | AltAsn : B         -> asn A B
    .Inductive asn (A:Set) (B:Set) : Set :=
      | VarAsn : atom -> A -> asn A B
      | AltAsn : B         -> asn A B
    .Definition map (f1 : A -> A) (f2: B -> B) (E : list (asn A B)) : list (asn A B) :=
      List.map (fun x => match x with
                         | VarAsn _ x a => VarAsn B x (f1 a)
                         | AltAsn _ b   => AltAsn A (f2 b)
                         end) E.Fixpoint dom (A: Set) (B: Set) (E : list (asn A B)) {struct E} : atoms :=
      match E with
        | nil => empty
        | (VarAsn _ x _) :: E' => add x (dom E')
        | _ :: E' => dom E'
      end.Definition disjoint (E : list (asn A B)) (F : list (asn A B)) : Prop :=
      Subset (inter (dom E) (dom F)) empty.Definition binds (x : atom) (a : A) (E : list (asn A B)) : Prop :=
      List.In (VarAsn  B x a) E.Definition bindsAlt (b : B) (E : list (asn A B)) : Prop :=
      List.In (AltAsn A b) E.Local Notation "x ~~ a" := (one (VarAsn B x a)) (at level 68).Local Notation "x `notin` E" :=
    (~ In x E)
    (at level 70).Fixpoint erase (E : list (asn A B)) : list B :=
      match E with
      | nil => nil
      | (AltAsn _ b) :: E => b :: erase E
      | (VarAsn _ x a) :: E => erase E
      end.(* ********************************************************************* *)
  (** ** Local notations *)

  (** We make a local notation for [one], and for operations and
      predicate on finite sets, in order to make the statements of the
      lemmas below more readable.  The notations are local so that
      users of this functor may choose their own notations. *)

  Local Notation "[ i ]" := (one i).(*  Local Notation "x ~~ T" := (one (VarAsn B x T)) (at level 68). *)

  Local Notation "E `union` F" :=
    (union E F)
    (at level 65, right associativity).Local Notation "x `in` E" :=
    (In x E)
    (at level 70).Local Notation "E [=] F" :=
    (Equal E F)
    (at level 70, no associativity).Local Notation "E [<=] F" :=
    (Subset E F)
    (at level 70, no associativity).

(* Specifications: *)
Lemma cons_app_one : cons x l = [ x ] ++ l.
Lemma cons_app_assoc : (cons x l1) ++ l2 = cons x (l1 ++ l2).
Lemma app_assoc : (l1 ++ l2) ++ l3 = l1 ++ (l2 ++ l3).
Lemma app_nil_1 : nil ++ l = l.
Lemma app_nil_2 : l ++ nil = l.
Lemma in_one : List.In x [ y ] <-> x = y.
Lemma in_app : List.In x (l1 ++ l2) <-> List.In x l1 \/ List.In x l2.
Lemma one_eq_app : [ x ] ++ l1 = l2 ++ l3 -> (exists qs, l2 = x :: qs /\ l1 = qs ++ l3) \/ (l2 = nil /\ l3 = x :: l1).
Lemma app_eq_one : l2 ++ l3 = [ x ] ++ l1 -> (exists qs, l2 = x :: qs /\ l1 = qs ++ l3) \/ (l2 = nil /\ l3 = x :: l1).
Lemma nil_neq_one_mid : nil <> l1 ++ [ x ] ++ l2.
Lemma one_mid_neq_nil : l1 ++ [ x ] ++ l2 <> nil.
Lemma map_nil : map f1 f2 nil = nil.
Lemma map_consVar : map f1 f2 ((VarAsn B x b) :: E) = (VarAsn B x (f1 b)) :: map f1 f2 E.
Lemma map_consAlt : map f1 f2 ((AltAsn A a) :: E) = (AltAsn A (f2 a)) :: map f1 f2 E.
Lemma map_oneVar : map f1 f2 (one (VarAsn B x b)) = one (VarAsn B x (f1 b)).
Lemma map_oneAlt : map f1 f2 (one (AltAsn A a)) = one (AltAsn A (f2 a)).
Lemma map_app : map f1 f2 (E ++ F) = map f1 f2 E ++ map f1 f2 F.
Lemma dom_nil : (@dom A B nil) = empty.