(* ---------------------------------------------------------------------- *)
(** **** Properties of remove *)

(* Specifications: *)
(** Remove is identity on empty environments. *)
Axiom remove_empty : forall A x,
(@empty A) ∖ {x} = (@empty A).
(** Remove on singular. *)
Axiom remove_single_eq : forall A x y (v : A),
x = y ->
(x ∶ v) ∖ {y} = (@empty A).
Axiom remove_single_neq : forall A x y (v : A),
x <> y ->
(x ∶ v) ∖ {y} = (x ∶ v).
(** Remove and notin and belongs. *)
Axiom remove_notin : forall A x (E : gen_env A),
x ∉ E ->
E ∖ {x} = E.
Axiom notin_remove_notin : forall A x y (E : gen_env A),
x ∉ E ->
x ∉ (E ∖ {y}).
Axiom all_notin_remove_notin : forall A xs y (E : gen_env A),
xs ⊄ E ->
xs ⊄ (E ∖ {y}).
Axiom belongs_remove : forall A x y (E : gen_env A),
x <> y -> x ∈ E ->
x ∈ (E ∖ {y}).
Axiom belongs_remove_inv : forall A x y (E : gen_env A),
ok E ->
x ∈ (E ∖ {y}) -> x <> y.
(** Remove and concatenation. *)
Axiom remove_belongs_concat_r : forall A x (E F : gen_env A),
x ∈ F ->
(E & F) ∖ {x} = E & (F ∖ {x}).
Axiom remove_belongs_concat_l : forall A x (E F : gen_env A),
x ∉ F ->
(E & F) ∖ {x} = (E ∖ {x}) & F.
(** Remove and belongs and all_belongs. *)
Axiom remove_ok_notin : forall A x (E : gen_env A),
ok E ->
x ∉ (E ∖ {x}).
Axiom remove_all_belongs : forall A x xs (F : gen_env A),
¬ List.In x xs -> (x :: xs) ⊂ F ->
xs ⊂ (F ∖ {x}).
(** Remove commutes with map and updating. *)
Axiom remove_map : forall A B (f : A -> B) (E : gen_env A) x,
(map f E) ∖ {x} = map f (E ∖ {x}).
Axiom remove_update : forall A x (E F : gen_env A),
ok E ->
(E ::= F) ∖ {x} = (E ∖ {x}) ::= F.
Axiom remove_update_eq : forall A x y (v : A) (E : gen_env A),
x = y ->
(E ::= (y ∶ v)) ∖ {x} = E ∖ {x}.
(** Ok and remove. *)
Axiom ok_remove : forall A x (E : gen_env A),
ok E ->
ok (E ∖ {x}).
Lemma remove_empty : forall x,
(@empty A) ∖ {x} = (@empty A).
Lemma notin_remove_notin : forall x y E,
x ∉ E ->
x ∉ (E ∖ {y}).
Lemma all_notin_remove_notin : forall xs y E,
xs ⊄ E ->
xs ⊄ (E ∖ {y}).
Lemma belongs_remove : forall x y E,
x <> y -> x ∈ E ->
x ∈ (E ∖ {y}).
Lemma belongs_remove_inv : forall x y E,
ok E ->
x ∈ (E ∖ {y}) -> x <> y.
Lemma remove_belongs_concat_r : forall x E F,
x ∈ F ->
(E & F) ∖ {x} = E & (F ∖ {x}).
Lemma remove_belongs_concat_l : forall x E F,
x ∉ F ->
(E & F) ∖ {x} = (E ∖ {x}) & F.
Lemma remove_ok_notin : forall x E,
ok E ->
x ∉ (E ∖ {x}).
Lemma remove_all_belongs : forall x xs F,
¬ List.In x xs -> (x :: xs) ⊂ F ->
xs ⊂ (F ∖ {x}).
Lemma remove_map : forall f E x,
(map f E) ∖ {x} = map f (E ∖ {x}).
Lemma remove_update_one : forall x y v E,
ok E ->
(update_one E y v) ∖ {x} = update_one (E ∖ {x}) y v.
Lemma remove_update : forall x E F,
ok E ->
(E ::= F) ∖ {x} = (E ∖ {x}) ::= F.
Lemma remove_update_eq : forall x y v E,
x = y ->
(E ::= (y ∶ v)) ∖ {x} = E ∖ {x}.
Lemma ok_remove : forall x E,
ok E ->
ok (E ∖ {x}).