(* ---------------------------------------------------------------------- *)
(** **** Properties of eq *)

(* Specifications: *)
(** Eq is reflexive, symmetric and transitive *)
Theorem eq_refl : forall A (E F : gen_env A),
E = F ->
E ≍ F.
(** Eq implements equivalence over bindings. *)
Theorem eq_binds : forall A x (v : A) (E F : gen_env A),
E ≍ F ->
binds x v E ->
binds x v F.
(** Concat is commutative with eq when ok. *)
Theorem eq_concat_comm : forall A (E F : gen_env A),
ok (E & F) ->
(E & F) ≍ (F & E).
(** Eq commutes with other operations on environments. *)
Theorem eq_get : forall A (E F : gen_env A),
E ≍ F ->
forall x, get x E = get x F.
Theorem eq_get_inv : forall A (E F : gen_env A),
(forall x, get x E = get x F) ->
E ≍ F.
Theorem eq_map : forall A B (f : A -> B) (E F : gen_env A),
E ≍ F ->
map f E ≍ map f F.
Theorem eq_map_inv : forall A B (f : A -> B) (E F : gen_env A),
Image.injective A B f ->
map f E ≍ map f F ->
E ≍ F.
Theorem eq_remove : forall A x (E F : gen_env A),
ok E -> ok F ->
E ≍ F ->
E ∖ {x} ≍ F ∖ {x}.
Theorem eq_all_remove : forall A xs (E F : gen_env A),
ok E -> ok F ->
E ≍ F ->
E ∖ xs ≍ F ∖ xs.
Theorem eq_update : forall A (E F G : gen_env A),
E ≍ F ->
(E ::= G) ≍ (F ::= G).
Theorem eq_belongs : forall A x (E F : gen_env A),
E ≍ F ->
x ∈ E ->
x ∈ F.
Theorem eq_all_belongs : forall A xs (E F : gen_env A),
E ≍ F ->
xs ⊂ E ->
xs ⊂ F.
Theorem eq_notin : forall A x (E F : gen_env A),
E ≍ F ->
x ∉ E ->
x ∉ F.
Theorem eq_all_notin : forall A xs (E F : gen_env A),
E ≍ F ->
xs ⊄ E ->
xs ⊄ F.
(** Decidability of eq. *)
Theorem eq_dec : forall A (E F : gen_env A),
(forall w w' : A, { w = w' } + { ¬ w = w' }) ->
ok E -> ok F ->
{ E ≍ F } + { ¬ E ≍ F }.