(** Map function on types. *)
(** Updating of types with bindings of another environment. *)
Parameter update_one : gen_env A -> TVar -> A -> gen_env A.
Parameter update : gen_env A -> gen_env A -> gen_env A.
(** Remove a binding from an environment. *)
Parameter remove : TVar -> gen_env A -> gen_env A.
Parameter all_remove : list TVar -> gen_env A -> gen_env A.
(** The ok predicate states that the bindings are pairwise distinct, i.e. each variable appears only once. *)
Inductive ok : gen_env A -> Prop :=
| ok_nil : ok empty
| ok_cons : forall x v F, ok F ∧ notin x F -> ok (concat F (single x v))
.
End CoreDefinitions.
(** [x ∶ v] is the notation for a singleton environment mapping x to v. *)
Notation "x '∶' v" := (single x v)
(at level 63) : gen_env_scope.
(** [xs ∷ vs] is the notation for an environment mapping xs to vs. *)
Notation "xs '∷' vs" := (singles xs vs)
(at level 63) : gen_env_scope.
(** [E & F] is the notation for concatenation of E and F. *)
Notation "E '&' F" := (concat E F)
(at level 65, left associativity) : gen_env_scope.
(** [E ∖ { x } ] is the notation for removing x from E. *)
Notation "E '∖' '{' x '}'" := (remove x E)
(at level 64, left associativity) : gen_env_scope.
(** [E ∖ xs ] is the notation for removing xs from E. *)
Notation "E '∖' xs" := (all_remove xs E)
(at level 64, left associativity) : gen_env_scope.
(** [E '[' x '<-' v ']' ] is the notation for updating x in E with v. *)
Notation "E '[' x '<-' v ']'" := (update_one E x v)
(at level 65, left associativity) : gen_env_scope.
(** [E ::= F] is the notation for updating of E with F. *)
Notation "E '::=' F" := (update E F)
(at level 65, left associativity) : gen_env_scope.
(** [x ∈ E] to be read x is bound in E. *)
Notation "x '∈' E" := (belongs x E)
(at level 67) : gen_env_scope.
(** [xs ⊂ E] to be read xs are bound in E. *)
Notation "xs '⊂' E" := (all_belongs xs E)
(at level 67) : gen_env_scope.
(** [x '∉' E] to be read x is unbound in E. *)
Notation "x '∉' E" := (notin x E)
(at level 67) : gen_env_scope.
(** [xs '⊄' E] to be read xs are unbound in E. *)
Notation "xs '⊄' E" := (all_notin xs E)
(at level 67) : gen_env_scope.
Bind Scope gen_env_scope with gen_env.
Delimit Scope gen_env_scope with gen_env.
Local Open Scope gen_env_scope.
(* ---------------------------------------------------------------------- *)
(** ** Properties *)
Section Properties.
Implicit Types x y : TVar.
Implicit Types xs ys : list TVar.
(* ---------------------------------------------------------------------- *)
(** *** Primary properties *)

(** Induction scheme over environments. *)
Axiom env_ind : forall A, forall P : gen_env A -> Prop,
(P (@empty A)) ->
(forall (E : gen_env A) x (v : A), P E -> P (E & (x ∶ v))) ->
(forall (E : gen_env A), P E).