(* ---------------------------------------------------------------------- *)
(** **** Properties of update_one *)

(* Specifications: *)
(** Update_one is identity on empty environments. *)
Axiom update_one_empty : forall A x (v : A),
(@empty A) [x <- v] = (@empty A).
(** Update_one with single. *)
Axiom update_one_single : forall A x y (v w : A),
x = y ->
(x ∶ v) [y <- w] = (x ∶ w).
Axiom update_one_single_neq : forall A x y (v w : A),
x <> y ->
(x ∶ v) [y <- w] = (x ∶ v).
(** Update_one and  concatenation. *)
Axiom update_one_concat_r : forall A x (v : A) (E F : gen_env A),
x ∈ F ->
(E & F) [x <- v] = E & (F [x <- v]).
Axiom update_one_concat_l : forall A x (v : A) (E F : gen_env A),
x ∉ F ->
(E & F) [x <- v] = (E [x <- v]) & F.
(** Dom is unchanged by updating. *)
Axiom dom_update_one : forall A x (v : A) (E : gen_env A),
dom (E [x <- v]) = dom E.
(** Belongs commutes with update. *)
Axiom belongs_update_one : forall A x y (v : A) (E : gen_env A),
y ∈ E ->
y ∈ (E [x <- v]).
Axiom belongs_update_one_inv : forall A x y (v : A) (E : gen_env A),
y ∈ (E [x <- v]) ->
y ∈ E.
(** All_belongs commutes with update. *)
Axiom all_belongs_update_one : forall A x xs (v : A) (E : gen_env A),
xs ⊂ E ->
xs ⊂ (E [x <- v]).
Axiom all_belongs_update_one_inv : forall A x xs (v : A) (E : gen_env A),
xs ⊂ (E [x <- v]) ->
xs ⊂ E.
(** Notin commutes with update. *)
Axiom notin_update_one : forall A x y (v : A) (E : gen_env A),
y ∉ E ->
y ∉ (E [x <- v]).
Axiom notin_update_one_inv : forall A x y (v : A) (E : gen_env A),
y ∉ (E [x <- v]) ->
y ∉ E.
(** All_notin commutes with update. *)
Axiom all_notin_update_one : forall A x xs (v : A) (E : gen_env A),
xs ⊄ E ->
xs ⊄ (E [x <- v]).
Axiom all_notin_update_one_inv : forall A x xs (v : A) (E : gen_env A),
xs ⊄ (E [x <- v]) ->
xs ⊄ E.
(** Update is identity when the domains are disjoints. *)
Axiom update_one_notin : forall A x (v : A) (E : gen_env A),
x ∉ E ->
E [x <- v] = E.
(** Update commutes with map. *)
Axiom map_update_one : forall A B (f : A -> B) x (v : A) (E : gen_env A),
map f (E [x <- v]) = (map f E) [x <- f v].
(** Ok commutes with update. *)
Axiom ok_update_one : forall A x (v : A) (E : gen_env A),
ok E ->
ok (E [x <- v]).
Axiom ok_update_one_inv : forall A x (v : A) (E : gen_env A),
ok (E [x <- v]) ->
ok E.
Lemma update_one_empty : forall x v,
(@empty A) [x <- v] = (@empty A).
Lemma update_one_single_neq : forall x y v w,
x <> y ->
(x ∶ v) [y <- w] = (x ∶ v).
Lemma update_one_concat_r : forall x v E F,
x ∈ F ->
(E & F) [x <- v] = E & (F [x <- v]).
Lemma update_one_concat_l : forall x v E F,
x ∉ F ->
(E & F) [x <- v] = (E [x <- v]) & F.
Lemma dom_update_one : forall x v E,
dom (E [x <- v]) = dom E.
Lemma belongs_update_one : forall x y v E,
y ∈ E ->
y ∈ (E [x <- v]).
Lemma belongs_update_one_inv : forall x y v E,
y ∈ (E [x <- v]) ->
y ∈ E.
Lemma all_belongs_update_one : forall x xs v E,
xs ⊂ E ->
xs ⊂ (E [x <- v]).
Lemma all_belongs_update_one_inv : forall x xs v E,
xs ⊂ (E [x <- v]) ->
xs ⊂ E.
Lemma notin_update_one : forall x y v E,
y ∉ E ->
y ∉ (E [x <- v]).
Lemma notin_update_one_inv : forall x y v E,
y ∉ (E [x <- v]) ->
y ∉ E.
Lemma all_notin_update_one : forall x xs v E,
xs ⊄ E ->
xs ⊄ (E [x <- v]).
Lemma all_notin_update_one_inv : forall x xs v E,
xs ⊄ (E [x <- v]) ->
xs ⊄ E.
Lemma update_one_notin : forall x v E,
x ∉ E ->
E [x <- v] = E.
Lemma map_update_one : forall f x v E,
map f (E [x <- v]) = (map f E) [x <- f v].
Lemma ok_update_one : forall x v E,
ok E ->
ok (E [x <- v]).
Lemma ok_update_one_inv : forall x v E,
ok (E [x <- v]) ->
ok E.