Definition eq_var_dec := VarType.eq_dec.(** Asserts the binding of a variable in an environment. *)
Definition binds (x : TVar) (v : A) (E : gen_env A) := get x E = Some v.(** Asserts the inclusion of an environment in another. *)
Definition all_binds (E F : gen_env A) :=
  forall x v, binds x v E -> binds x v F.(** Equivalence between environments *)
Definition eq (E F : gen_env A) := all_binds E F ∧ all_binds F E.(** [x '∹' v '⋲' E] to be read x is bound to v in E. *)

Notation "x '∹' v '⋲' E" := (binds x v E) 
  (at level 65) : gen_env_scope.(** [E '⊏' F] to be read F all_binds E, i.e. E is included in F. *)

Notation "E '⊏' F" := (all_binds E F) 
  (at level 65) : gen_env_scope.(** [E '≍' F] to be read F is equivalent to E, i.e. E binds as F. *)

Notation "E '≍' F" := (eq E F) 
  (at level 68) : gen_env_scope.Implicit Types x y : TVar.Implicit Types xs ys : list TVar.

Theorem ok_dom_inv : forall A (E : gen_env A), ok E -> List.NoDup (dom E).