(* ---------------------------------------------------------------------- *)
(** **** Properties of all_remove *)

(* Specifications: *)
(** All_remove and remove. *)
Axiom all_remove_remove : forall A x xs (E : gen_env A),
E ∖ (x :: xs) = (E ∖ {x}) ∖ xs.
(** All_remove is identity on empty environments. *)
Axiom all_remove_empty : forall A xs,
(@empty A) ∖ xs = (@empty A).
Axiom all_remove_nil : forall A (E : gen_env A),
E ∖ nil = E.
(** All_remove on singular. *)
Axiom all_remove_single_in : forall A x xs (v : A),
List.In x xs ->
(x ∶ v) ∖ xs = (@empty A).
Axiom all_remove_single_not_in : forall A x xs (v : A),
¬ List.In x xs ->
(x ∶ v) ∖ xs = (x ∶ v).
(** All_remove on singulars. *)
Axiom all_remove_singles_in : forall A xs ys (vs : list A),
xs = ys -> length xs = length vs ->
(xs ∷ vs) ∖ ys = (@empty A).
Axiom all_remove_singles_not_in : forall A xs ys (vs : list A),
List.Forall (fun x => ¬ List.In x xs) ys ->
(xs ∷ vs) ∖ ys = (xs ∷ vs).
(** All_remove and notin. *)
Axiom all_remove_notin : forall A xs (E : gen_env A),
xs ⊄ E ->
E ∖ xs = E.
Axiom notin_all_remove_notin : forall A x ys (E : gen_env A),
x ∉ E ->
x ∉ (E ∖ ys).
Axiom all_notin_all_remove_notin : forall A xs ys (E : gen_env A),
xs ⊄ E ->
xs ⊄ (E ∖ ys).
(** Remove and all_notin. *)
Axiom all_remove_ok_notin : forall A xs (E : gen_env A),
ok E ->
xs ⊄ (E ∖ xs).
(** All_remove and concatenation. *)
Axiom all_remove_belongs_concat_r : forall A xs (E F : gen_env A),
List.NoDup xs ->
xs ⊂ F ->
(E & F) ∖ xs = E & (F ∖ xs).
Axiom all_remove_belongs_concat_l : forall A xs (E F : gen_env A),
xs ⊄ F ->
(E & F) ∖ xs = (E ∖ xs) & F.
(** All_remove commutes with map and updating. *)
Axiom all_remove_map : forall A B (f : A -> B) (E : gen_env A) xs,
(map f E) ∖ xs = map f (E ∖ xs).
Axiom all_remove_update : forall A xs (E F : gen_env A),
ok E ->
(E ::= F) ∖ xs = (E ∖ xs) ::= F.
(** Ok and all_remove. *)
Axiom ok_all_remove : forall A xs (E : gen_env A),
ok E ->
ok (E ∖ xs).
Lemma all_remove_remove : forall x xs E,
E ∖ (x :: xs) = (E ∖ {x}) ∖ xs.
Lemma all_remove_single_not_in : forall x xs v,
¬ List.In x xs ->
(x ∶ v) ∖ xs = (x ∶ v).
Lemma all_remove_singles_in : forall xs ys vs,
xs = ys -> length xs = length vs ->
(xs ∷ vs) ∖ ys = (@empty A).
Lemma all_remove_singles_not_in : forall xs ys vs,
List.Forall (fun x => ¬ List.In x xs) ys ->
(xs ∷ vs) ∖ ys = (xs ∷ vs).
Lemma all_remove_notin : forall xs E,
xs ⊄ E ->
E ∖ xs = E.
Lemma notin_all_remove_notin : forall x ys E,
x ∉ E ->
x ∉ (E ∖ ys).
Lemma all_notin_all_remove_notin : forall xs ys E,
xs ⊄ E ->
xs ⊄ (E ∖ ys).
Lemma all_remove_ok_notin : forall xs E,
ok E ->
xs ⊄ (E ∖ xs).
Lemma all_remove_belongs_concat_r : forall xs E F,
List.NoDup xs ->
xs ⊂ F ->
(E & F) ∖ xs = E & (F ∖ xs).
Lemma all_remove_belongs_concat_l : forall xs E F,
xs ⊄ F ->
(E & F) ∖ xs = (E ∖ xs) & F.
Lemma all_remove_map : forall f E xs,
(map f E) ∖ xs = map f (E ∖ xs).
Lemma all_remove_update : forall xs E F,
ok E ->
(E ::= F) ∖ xs = (E ∖ xs) ::= F.
Lemma ok_all_remove : forall xs E,
ok E ->
ok (E ∖ xs).