(* ---------------------------------------------------------------------- *)
(** **** Properties of ok *)

(* Specifications: *)
(** Ok stands for empty and singular environments. *)
Axiom ok_empty : forall A,
ok (@empty A).
Axiom ok_single : forall A x (v : A),
ok (x ∶ v).
(** Ok stands if there is no variable duplication. *)
Axiom ok_singles : forall A xs (vs : list A),
List.NoDup xs ->
ok (xs ∷ vs).
Axiom ok_singles_inv : forall A xs (vs : list A),
length xs = length vs ->
ok (xs ∷ vs) ->
List.NoDup xs.
(** Ok stands on concatenation when domains are disjoints. *)
Axiom ok_concat : forall A (E F : gen_env A),
ok E -> ok F ->
(dom E) ⊄ F -> (dom F) ⊄ E ->
ok (E & F).
Axiom ok_concat_inv : forall A (E F : gen_env A),
ok (E & F) ->
ok E ∧ ok F ∧ (dom E) ⊄ F ∧ (dom F) ⊄ E.
Axiom ok_concat_comm : forall A (E F : gen_env A),
ok (E & F) ->
ok (F & E).
(** Belongs and concat with ok. *)
Axiom belongs_ok_concat_inv_l : forall A x (F G : gen_env A),
ok (F & G) ->
x ∈ F ->
x ∉ G.
Axiom belongs_ok_concat_inv_r : forall A x (F G : gen_env A),
ok (F & G) ->
x ∈ G ->
x ∉ F.
Axiom concat_not_ok : forall A x (F G : gen_env A),
x ∈ F -> x ∈ G ->
¬ ok (F & G).
Lemma ok_empty :
ok (@empty A).
Lemma ok_singles : forall xs vs,
List.NoDup xs ->
ok (xs ∷ vs).
Lemma ok_singles_inv : forall xs vs,
length xs = length vs ->
ok (xs ∷ vs) ->
List.NoDup xs.
Lemma ok_concat : forall E F,
ok E -> ok F ->
(dom E) ⊄ F -> (dom F) ⊄ E ->
ok (E & F).
Lemma ok_concat_inv : forall E F,
ok (E & F) ->
ok E ∧ ok F ∧ (dom E) ⊄ F ∧ (dom F) ⊄ E.
Lemma ok_concat_comm : forall E F,
ok (E & F) ->
ok (F & E).
Lemma belongs_ok_concat_inv_l : forall x F G,
ok (F & G) ->
x ∈ F ->
x ∉ G.
Lemma belongs_ok_concat_inv_r : forall x F G,
ok (F & G) ->
x ∈ G ->
x ∉ F.
Lemma concat_not_ok : forall x F G,
x ∈ F -> x ∈ G ->
¬ ok (F & G).