Library Generic_Env


Require Import Utf8.
Set Implicit Arguments.

Module Type of an implementation of environments


Require Import Generic_Var.

Module Type Generic_Env_Type (Var : Generic_Var).
Require Import List.
Require Sets.Image.
Import Var.

Definitions and Notations


gen_env A is an environment that binds variables to values of type A.
Parameter gen_env : Type -> Type.

Section Core_Definitions.

Variable A B : Type.

The decidability of equality on keys (variables) is imported from Var.
Definition eq_keys_dec := Var.eq_var_dec.

Empty environment.
Parameter empty : gen_env A.

Environment build upon explicit associations.
Parameter single : TVar -> A -> gen_env A.
Parameter singles : list TVar -> list A -> gen_env A.

Concatenation of environment (the second one binds first).
Parameter concat : gen_env A -> gen_env A -> gen_env A.

The main operation on environment, get the type of a variable.
Parameter get : TVar -> gen_env A -> option A.

Domain and image of an environment.
Parameter dom : gen_env A -> list TVar.
Parameter img : gen_env A -> list A.

Check the occurence of variable(s) in an environment.
Parameter belongs : TVar -> gen_env A -> Prop.
Parameter all_belongs : list TVar -> gen_env A -> Prop.

Check the non-occurence of variable(s) in an environment.
Parameter notin : TVar -> gen_env A -> Prop.
Parameter all_notin : list TVar -> gen_env A -> Prop.

Map function on types.
Parameter map : (A -> B) -> gen_env A -> gen_env B.

Updating of types with bindings of another environment.
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.

End Core_Definitions.

xv is the notation for a singleton environment mapping x to v.

Notation "x '∶' v" := (single x v)
  (at level 63) : gen_env_scope.

xsvs 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.

Exs is the notation for removing xs from E.

Notation "E '∖' xs" := (all_remove xs E)
  (at level 64, 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.

xE to be read x is bound in E.

Notation "x '∈' E" := (belongs x E)
  (at level 67) : gen_env_scope.

xsE 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.

Section Prop_Definitions.

Variable A : Type.

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 A)
| ok_cons : forall x v F, ok F x F -> ok (F & (x v))
.

Asserts the binding of a variable in an environment.
Definition binds (x : TVar) (v : A) (E : gen_env A) := get x E = Some v.

Asserts the inclusion of an environment in another.
Definition all_binds (E F : gen_env A) :=
  forall x v, binds x v E -> binds x v F.

Equivalence on environments
Definition eq (E F : gen_env A) := all_binds E F all_binds F E.

End Prop_Definitions.

x '∹' v '⋲' E to be read x is bound to v in E.

Notation "x '∹' v '⋲' E" := (binds x v E)
  (at level 65) : gen_env_scope.

E '⊏' F to be read F all_binds E, i.e. E is included in F.

Notation "E '⊏' F" := (all_binds E F)
  (at level 65) : gen_env_scope.

E '≍' F to be read F is equivalent to E, i.e. E binds as F.

Notation "E '≍' F" := (eq E F)
  (at level 68) : 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.
Variable A B : Type.
Implicit Types x y : TVar.
Implicit Types xs ys : list TVar.
Implicit Types v w : A.
Implicit Types vs ws : list A.
Implicit Types E F G : gen_env A.
Implicit Types f g : A -> B.

Primary properties


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

Properties of singulars


Environment built from lists.
Parameter singles_empty :
  nil nil = (@empty A).
Parameter singles_cons : forall x xs v vs,
  (x :: xs) (v :: vs) = (xs vs) & (x v).

Properties of concatenation


Concatenation admits empty as neutral element, and is associative.
Parameter concat_empty_r : forall E,
  E & (@empty A) = E.
Parameter concat_empty_l : forall E,
  (@empty A) & E = E.
Parameter concat_assoc : forall E F G,
  E & (F & G) = (E & F) & G.

Properties of get


Get is None on empty.
Parameter get_empty : forall x,
  get x (@empty A) = None.

Get is Some when it binds.
Parameter get_single_eq : forall x y v,
  x = y ->
  get x (y v) = Some v.

Get is decidable.
Parameter get_dec : forall x E,
   { v : A | get x E = Some v } + { get x E = None }.

Properties of dom


Dom builds a list.
Parameter dom_empty :
  dom (@empty A) = nil.
Parameter dom_empty_inv : forall E,
  dom (E) = nil ->
  E = (@empty A).
Parameter dom_single : forall x v,
  dom (x v) = (x :: nil).
Parameter dom_singles : forall xs vs,
  length xs = length vs ->
  dom (xs vs) = xs.
Parameter dom_singles_incl : forall xs vs,
  List.incl (dom (xs vs)) xs.
Parameter dom_concat : forall E F,
  dom (E & F) = List.app (dom F) (dom E).

Properties of img


Img builds a list.
Parameter img_empty :
  img (@empty A) = nil.
Parameter img_empty_inv : forall E,
  img (E) = nil ->
  E = (@empty A).
Parameter img_single : forall x v,
  img (x v) = v :: nil.
Parameter img_singles : forall xs vs,
  length xs = length vs ->
  img (xs vs) = vs.
Parameter img_singles_incl : forall xs vs,
  List.incl (img (xs vs)) vs.
Parameter img_concat : forall E F,
  img (E & F) = List.app (img F) (img E).

Dom and img builds identity.
Parameter dom_img_id : forall E,
  (dom E) (img E) = E.
Parameter length_dom_img_eq : forall E,
  length (dom E) = length (img E).

Properties of belongs


Belongs is false on empty environments.
Parameter belongs_empty : forall x,
  x (@empty A) ->
  False.

Belongs in singular(s).
Parameter belongs_single : forall x y v,
  x = y ->
  x (y v).
Parameter belongs_single_inv : forall x y v,
  x (y v) ->
  x = y.
Parameter belongs_singles : forall x xs vs,
  length xs = length vs ->
  List.In x xs ->
  x (xs vs).
Parameter belongs_singles_inv : forall x xs vs,
  length xs = length vs ->
  x (xs vs) ->
  List.In x xs.

Belongs and concatenation.
Parameter belongs_concat_l : forall x F G,
  x F ->
  x (F & G).
Parameter belongs_concat_r : forall x F G,
  x F ->
  x (G & F).
Parameter belongs_concat_inv : forall x F G,
  x (F & G) ->
  x F x G.

Belongs and dom.
Parameter belongs_dom : forall x E,
  x E ->
  List.In x (dom E).
Parameter belongs_dom_inv : forall x E,
  List.In x (dom E) ->
  x E.

Properties of all_belongs


All_belongs and belongs.
Parameter all_belongs_belongs : forall x xs E,
  (x :: xs) E ->
  x E xs E.
Parameter belongs_all_belongs : forall x xs E,
  x E xs E ->
  (x :: xs) E.

All_belongs is false on empty environments.
Parameter all_belongs_empty : forall xs,
  xs (@empty A) ->
  xs = nil.
Parameter all_belongs_nil : forall E,
  nil E.

All_belongs in singular(s).
Parameter all_belongs_single : forall xs y v,
  xs = y :: nil ->
  xs (y v).
Parameter all_belongs_single_inv : forall xs y v,
  length xs = 1 ->
  xs (y v) ->
  xs = y :: nil.
Parameter all_belongs_singles : forall xs ys vs,
  length ys = length vs ->
  List.incl xs ys ->
  xs (ys vs).
Parameter all_belongs_singles_inv : forall xs ys vs,
  xs (ys vs) ->
  List.incl xs ys.

All_belongs and concatenation.
Parameter all_belongs_concat_l : forall xs F G,
  xs F ->
  xs (F & G).
Parameter all_belongs_concat_r : forall xs F G,
  xs F ->
  xs (G & F).

All_belongs and dom.
Parameter all_belongs_dom : forall xs E,
  xs E ->
  List.incl xs (dom E).
Parameter all_belongs_dom_inv : forall xs E F,
  List.incl xs (dom E) ->
  xs E.

Properties of notin


Notin and belongs.
Parameter notin_belongs : forall x E,
  x E ->
  ¬ x E.
Parameter belongs_notin : forall x E,
  x E ->
  ¬ x E.
Parameter notin_belongs_neq : forall x y E,
  x E -> y E ->
  x <> y.

Notin is true on empty environments.
Parameter notin_empty : forall x,
  x (@empty A).

Notin in singular(s).
Parameter notin_single : forall x y v,
  x <> y ->
  x (y v).
Parameter notin_single_inv : forall x y v,
  x (y v) ->
  x <> y.
Parameter notin_singles : forall x xs vs,
  ¬ List.In x xs ->
  x (xs vs).
Parameter notin_singles_inv : forall x xs vs,
  length xs = length vs ->
  x (xs vs) ->
  ¬ List.In x xs.

Notin and concatenation.
Parameter notin_concat : forall x F G,
  x F -> x G ->
  x (F & G).
Parameter notin_concat_inv : forall x F G,
  x (F & G) ->
  x F x G.

Notin and dom.
Parameter notin_dom : forall x E,
  x E ->
  ¬ List.In x (dom E).
Parameter notin_dom_inv : forall x E F,
  ¬ List.In x (dom E) ->
  x E.

Properties of all_notin


All_notin is true on empty lists.
Parameter all_notin_empty_l : forall E,
  nil E.

All_notin and notin.
Parameter all_notin_notin : forall x xs E,
  (x :: xs) E ->
  x E xs E.
Parameter notin_all_notin : forall x xs E,
  x E xs E ->
  (x :: xs) E.

All_notin and belongs.
Parameter all_notin_belongs_neq : forall x ys E,
  x E -> ys E ->
  ¬ List.In x ys.

All_notin is true on empty environments.
Parameter all_notin_empty_r : forall xs,
  xs (@empty A).

All_notin in singular(s).
Parameter all_notin_single : forall xs y v,
  ¬ List.In y xs ->
  xs (y v).
Parameter all_notin_single_inv : forall xs y v,
  xs (y v) ->
  ¬ List.In y xs.
Parameter all_notin_singles : forall xs ys vs,
  List.Forall (fun x => ¬ List.In x ys) xs ->
  xs (ys vs).
Parameter all_notin_singles_inv : forall xs ys vs,
  length ys = length vs ->
  xs (ys vs) ->
  List.Forall (fun x => ¬ List.In x ys) xs.

All_notin and concatenation.
Parameter all_notin_concat : forall xs F G,
  xs F -> xs G ->
  xs (F & G).
Parameter all_notin_concat_inv : forall xs F G,
  xs (F & G) ->
  xs F xs G.

All_notin and dom.
Parameter all_notin_dom : forall xs E,
  xs E ->
  List.Forall (fun x => ¬ List.In x (dom E)) xs.
Parameter all_notin_dom_inv : forall xs E,
  List.Forall (fun x => ¬ List.In x (dom E)) xs ->
  xs E.

Properties of ok


Ok is equivalent to the non-duplication of the domain.
Parameter ok_NoDup_dom_eq : forall E,
  ok E <-> List.NoDup (dom E).

Ok stands for empty and singular environments.
Parameter ok_empty :
  ok (@empty A).
Parameter ok_single : forall x v,
  ok (x v).

Ok stands if there is no variable duplication.
Parameter ok_singles : forall xs vs,
  List.NoDup xs ->
  ok (xs vs).
Parameter ok_singles_inv : forall xs vs,
  length xs = length vs ->
  ok (xs vs) ->
  List.NoDup xs.

Ok stands on concatenation when domains are disjoints.
Parameter ok_concat : forall E F,
  ok E -> ok F ->
  (dom E) F -> (dom F) E ->
  ok (E & F).
Parameter ok_concat_inv : forall E F,
  ok (E & F) ->
  ok E ok F (dom E) F (dom F) E.
Parameter ok_concat_comm : forall E F,
  ok (E & F) ->
  ok (F & E).

Belongs and concat with ok.
Parameter belongs_ok_concat_inv_l : forall x F G,
  ok (F & G) ->
  x F ->
  x G.
Parameter belongs_ok_concat_inv_r : forall x F G,
  ok (F & G) ->
  x G ->
  x F.
Parameter concat_not_ok : forall x F G,
  x F -> x G ->
  ¬ ok (F & G).

Ok and dom
Parameter ok_dom : forall E,
  List.NoDup (dom E) -> ok E.
Parameter ok_dom_inv : forall E,
  ok E -> List.NoDup (dom E).

Properties of map


Map is applied on type(s).
Parameter map_empty : forall f,
  map f (@empty A) = (@empty B).
Parameter map_single : forall f x v,
  map f (x v) = x (f v).
Parameter map_singles : forall f xs vs,
  map f (xs vs) = xs (List.map f vs).

Map commutes with concatenation.
Parameter map_concat : forall f E F,
  map f (E & F) = (map f E) & (map f F).

Dom is unchanged by map.
Parameter dom_map : forall E f,
  dom (map f E) = dom E.

Belongs commutes with map.
Parameter belongs_map : forall x E f,
  x E ->
  x (map f E).
Parameter belongs_map_inv : forall x E f,
  x (map f E) ->
  x E.

All_belongs commutes with map.
Parameter all_belongs_map : forall xs E f,
  xs E ->
  xs (map f E).
Parameter all_belongs_map_inv : forall xs E f,
  xs (map f E) ->
  xs E.

Notin commutes with map.
Parameter notin_map : forall x E f,
  x E ->
  x (map f E).
Parameter notin_map_inv : forall x E f,
  x (map f E) ->
  x E.

All_notin commutes with map.
Parameter all_notin_map : forall xs E f,
  xs E ->
  xs (map f E).
Parameter all_notin_map_inv : forall xs E f,
  xs (map f E) ->
  xs E.

Ok commutes with map.
Parameter ok_map : forall E f,
  ok E ->
  ok (map f E).
Parameter ok_map_inv : forall E f,
  ok (map f E) ->
  ok E.

Properties of update


Update is identity in presence of empty environments.
Parameter update_empty_r : forall E,
  E ::= (@empty A) = E.
Parameter update_empty_l : forall E,
  (@empty A) ::= E = (@empty A).

Update with single.
Parameter update_single : forall x v y w,
  x = y ->
  (x v) ::= (y w) = (x w).
Parameter update_single_neq : forall x v y w,
  x <> y ->
  (x v) ::= (y w) = (x v).

Update commutes with concatenation on the right.
Parameter update_concat_r : forall E F G,
  E ::= (F & G) = (E ::= F) ::= G.

Dom is unchanged by updating.
Parameter dom_update : forall E F,
  dom (E ::= F) = dom E.

Belongs commutes with update.
Parameter belongs_update : forall x E F,
  x E ->
  x (E ::= F).
Parameter belongs_update_inv : forall x E F,
  x (E ::= F) ->
  x E.

All_belongs commutes with update.
Parameter all_belongs_update : forall xs E F,
  xs E ->
  xs (E ::= F).
Parameter all_belongs_update_inv : forall xs E F,
  xs (E ::= F) ->
  xs E.

Notin commutes with update.
Parameter notin_update : forall x E F,
  x E ->
  x (E ::= F).
Parameter notin_update_inv : forall x E F,
  x (E ::= F) ->
  x E.

All_notin commutes with update.
Parameter all_notin_update : forall xs E F,
  xs E ->
  xs (E ::= F).
Parameter all_notin_update_inv : forall xs E F,
  xs (E ::= F) ->
  xs E.

Update is identity when the domains are disjoints.
Parameter update_notin : forall E F,
  (dom F) E ->
  E ::= F = E.

Update commutes with map.
Parameter map_update : forall f E F,
  map f (E ::= F) = (map f E) ::= (map f F).

Ok commutes with update.
Parameter ok_update : forall E F,
  ok E ->
  ok (E ::= F).
Parameter ok_update_inv : forall E F,
  ok (E ::= F) ->
  ok E.

Update commutes with concatenation on the left.
Parameter update_concat_l : forall E F G,
  ok (E & F) ->
  (E & F) ::= G = (E ::= G) & (F ::= G).

Properties of remove


Remove is identity on empty environments.
Parameter remove_empty : forall x,
  (@empty A) {x} = (@empty A).

Remove on singular.
Parameter remove_single_eq : forall x v y,
  x = y ->
  (x v) {y} = (@empty A).
Parameter remove_single_not_eq : forall x v y,
  x <> y ->
  (x v) {y} = (x v).

Remove and notin and belongs.
Parameter remove_notin : forall x E,
  x E ->
  E {x} = E.
Parameter notin_remove_notin : forall x y E,
  x E ->
  x (E {y}).
Parameter all_notin_remove_notin : forall xs y E,
  xs E ->
  xs (E {y}).
Parameter belongs_remove : forall x y E,
  x <> y -> x E ->
  x (E {y}).
Parameter belongs_remove_inv : forall x y E,
  ok E ->
  x (E {y}) -> x <> y.

Remove and concatenation.
Parameter remove_belongs_concat_r : forall x E F,
  x F ->
  (E & F) {x} = E & (F {x}).
Parameter remove_belongs_concat_l : forall x E F,
  x F ->
  (E & F) {x} = (E {x}) & F.

Remove and belongs and all_belongs.
Parameter remove_ok_notin : forall x E,
  ok E ->
  x (E {x}).
Parameter remove_all_belongs : forall x xs F,
  ¬ List.In x xs -> (x :: xs) F ->
  xs (F {x}).

Remove commutes with map and updating.
Parameter remove_map : forall f E x,
  (map f E) {x} = map f (E {x}).
Parameter remove_update : forall x E F,
  ok E ->
  (E ::= F) {x} = (E {x}) ::= F.
Parameter remove_update_eq : forall x y v E,
  x = y ->
  (E ::= (y v)) {x} = E {x}.

Ok and remove.
Parameter ok_remove : forall x E,
  ok E ->
  ok (E {x}).

Properties of all_remove


All_remove and remove.
Parameter all_remove_remove : forall x xs E,
  E (x :: xs) = (E {x}) xs.

All_remove is identity on empty environments.
Parameter all_remove_empty : forall xs,
  (@empty A) xs = (@empty A).

All_remove on singular.
Parameter all_remove_single_in : forall x v xs,
  List.In x xs ->
  (x v) xs = (@empty A).
Parameter all_remove_single_not_in : forall x v xs,
  ¬ List.In x xs ->
  (x v) xs = (x v).

All_remove on singulars.
Parameter all_remove_singles_in : forall xs vs ys,
  xs = ys -> length xs = length vs ->
  (xs vs) ys = (@empty A).
Parameter all_remove_singles_not_in : forall xs vs ys,
  List.Forall (fun x => ¬ List.In x xs) ys ->
  (xs vs) ys = (xs vs).

All_remove and notin.
Parameter all_remove_notin : forall xs E,
  xs E ->
  E xs = E.
Parameter notin_all_remove_notin : forall x ys E,
  x E ->
  x (E ys).
Parameter all_notin_all_remove_notin : forall xs ys E,
  xs E ->
  xs (E ys).

Remove and all_notin.
Parameter all_remove_ok_notin : forall xs E,
  ok E ->
  xs (E xs).

All_remove and concatenation.
Parameter all_remove_belongs_concat_r : forall xs E F,
  List.NoDup xs ->
  xs F ->
  (E & F) xs = E & (F xs).
Parameter all_remove_belongs_concat_l : forall xs E F,
  xs F ->
  (E & F) xs = (E xs) & F.

All_remove commutes with map and updating.
Parameter all_remove_map : forall f E xs,
  (map f E) xs = map f (E xs).
Parameter all_remove_update : forall xs E F,
  ok E ->
  (E ::= F) xs = (E xs) ::= F.

Ok and all_remove.
Parameter ok_all_remove : forall xs E,
  ok E ->
  ok (E xs).

Properties of binds


Binds and empty.
Parameter binds_empty : forall x v,
  x v (@empty A) ->
  False.

Binds on singular(s).
Parameter binds_single : forall x v y w,
  x = y -> v = w ->
  x v (y w).
Parameter binds_single_inv : forall x v y w,
  x v (y w) ->
  x = y v = w.
Parameter binds_singles : forall x v y w ys ws,
  x = y -> v = w ->
  x v (y :: ys w :: ws).
Parameter binds_singles_inv : forall x v y w ys ws,
  x v (y :: ys w :: ws) ->
  (x = y v = w) (x v (ys ws)).

Binds is functional.
Parameter binds_eq_inv : forall x v w E,
  x v E -> x w E ->
  v = w.

Binds and concatenation.
Parameter binds_concat_r : forall x v F G,
  x v G ->
  x v (F & G).
Parameter binds_concat_l : forall x v F G,
  x v F ->
  x G ->
  x v (F & G).
Parameter binds_concat_inv : forall x v F G,
  x v (F & G) ->
  (x v G) (x G x v F).

Binds and belongs.
Parameter binds_belongs : forall x v F,
  x v F ->
  x F.
Parameter belongs_binds : forall x F,
  x F ->
  exists v, x v F.

Binds and map.
Parameter binds_map : forall x v E f,
  x v E ->
  x (f v) (map f E).
Parameter binds_map_inv : forall x (w : B) E f,
  x w (map f E) ->
  exists v, x v E w = f v.

Binds and update.
Parameter binds_update_notin : forall x v F G,
  x v F ->
  x G ->
  x v (F ::= G).
Parameter binds_update_in : forall x v F G,
  x F ->
  x v G ->
  x v (F ::= G).
Parameter binds_update_self : forall x v F,
  x F ->
  x v (F ::= (x v)).
Parameter binds_update_inv : forall x v F G,
  x v (F ::= G) ->
  (x G x v F) (x F x v G).

Binds and remove.
Parameter binds_remove : forall x y v E,
  x <> y -> x v E ->
  x v (E {y}).
Parameter binds_remove_inv : forall x y v E,
  x <> y -> x v (E {y}) ->
  x v E.
Parameter binds_all_remove : forall x ys v E,
  ¬ List.In x ys -> x v E ->
  x v (E ys).
Parameter binds_all_remove_inv : forall x ys v E,
  ¬ List.In x ys -> x v (E ys) ->
  x v E.

Binds and ok.
Parameter binds_concat_ok_comm : forall x v F G,
  x v (F & G) ->
  ok (F & G) ->
  x v (G & F).

Decidability of binds.
Parameter binds_dec_exists : forall x E,
  { v | x v E } + { forall v, ¬ x v E }.
Parameter binds_dec : forall x v E,
  (forall w w', { w = w' } + { ¬ w = w' }) ->
  { x v E } + { ¬ x v E }.

Properties of all_binds


All_Binds and binds.
Parameter all_binds_binds : forall x v E,
  (x v) E ->
  x v E.
Parameter binds_all_binds : forall x v E,
  x v E ->
  (x v) E.

All_Binds and empty.
Parameter all_binds_empty_l : forall E,
  (@empty A) E.
Parameter all_binds_empty_r : forall E,
  E (@empty A) ->
  E = (@empty A).

All_Binds on singular.
Parameter all_binds_single_empty : forall x v,
  (x v) (@empty A) ->
  False.
Parameter all_binds_single_single : forall x v y w,
  x = y -> v = w ->
  (x v) (y w).
Parameter all_binds_single_single_inv : forall x v y w,
  (x v) (y w) ->
  x = y v = w.
Parameter all_binds_single_singles : forall x v y w ys ws,
  x = y -> v = w ->
  (x v) (y :: ys w :: ws).
Parameter all_binds_single_singles_inv : forall x v y w ys ws,
  (x v) (y :: ys w :: ws) ->
  (x = y v = w) ((x v) (ys ws)).
Parameter all_binds_single_eq_inv : forall x v w E,
  (x v) E -> (x w) E ->
  v = w.

All_Binds on singulars.
Parameter all_binds_singles_singles : forall xs vs ys ws,
  xs = ys -> vs = ws ->
  (xs vs) (ys ws).

All_Binds and concatenation.
Parameter all_binds_concat_r : forall E F G,
  E G ->
  E (F & G).
Parameter all_binds_concat_l : forall E F G,
  E F ->
  (dom E) G ->
  E (F & G).
Parameter all_binds_concat_compat : forall E F G,
  E F ->
  (E & G) (F & G).
Parameter all_binds_l_concat : forall E F G,
  E G -> F G ->
  (E & F) G.

All_Binds on singulars when ok.
Parameter all_binds_singles_eq_inv : forall xs vs vs' F,
  List.NoDup xs ->
  length xs = length vs ->
  length xs = length vs' ->
  xs vs F -> xs vs' F ->
  vs = vs'.

All_Binds and belongs.
Parameter all_binds_belongs : forall E F,
  E F ->
  (dom E) F.
Parameter belongs_all_binds : forall x F,
  x F ->
  exists v, (x v) F.
Parameter all_belongs_all_binds : forall xs F,
  xs F ->
  exists vs, (xs vs) F.

All_Binds and map.
Parameter all_binds_map : forall f E F,
  E F ->
  map f E map f F.
Parameter all_binds_map_inv : forall f E F,
  Image.injective A B f ->
  map f E map f F ->
  E F.

All_Binds and update.
Parameter all_binds_update_self : forall E F,
  (dom E) F ->
  E (F ::= E).
Parameter all_binds_update : forall E F G,
  E F ->
  (E ::= G) (F ::= G).

All_Binds and remove.
Parameter all_binds_remove : forall y E F,
  y E -> E F ->
  E (F {y}).
Parameter all_binds_remove_inv : forall y E F,
  y E -> E (F {y}) ->
  E F.
Parameter all_binds_all_remove : forall ys E F,
  ys E -> E F ->
  E (F ys).
Parameter all_binds_all_remove_inv : forall ys E F,
  ys E -> E (F ys) ->
  E F.
Parameter all_binds_remove_compat : forall x E F,
  ok E -> ok F ->
  E F ->
  E {x} F {x}.
Parameter all_binds_all_remove_compat : forall xs E F,
  ok E -> ok F ->
  E F ->
  E xs F xs.

All_Binds and ok
Parameter all_binds_ok_concat_inv : forall E F G,
  ok (E & F) ->
  (E & F) G ->
  E G F G.
Parameter all_binds_concat_ok_comm : forall E F G,
  E (F & G) ->
  ok (F & G) ->
  E (G & F).

All_Binds is reflexive, anti-symmetric and transitive
Parameter all_binds_refl : forall E F,
  E = F ->
  E F.
Parameter all_binds_anti_sym : forall E F,
  E F -> F E ->
  E F.
Parameter all_binds_trans : forall E F G,
  E F -> F G ->
  E G.

Decidability of all_binds.
Parameter all_binds_dec_exists : forall xs F,
  List.NoDup xs ->
  { vs | length xs = length vs (xs vs) F }
  + { forall vs, length xs = length vs -> ¬ (xs vs) F }.

Properties of eq


Eq is reflexive, symmetric and transitive
Parameter eq_refl : forall E F,
  E = F ->
  E F.
Parameter eq_sym : forall E F,
  E F ->
  F E.
Parameter eq_trans : forall E F G,
  E F -> F G ->
  E G.

Eq implements equivalence over bindings.
Parameter eq_binds : forall x v E F,
  E F ->
  binds x v E ->
  binds x v F.

Concat is commutative with eq when ok.
Parameter eq_concat_comm : forall E F,
  ok (E & F) ->
  (E & F) (F & E).

Eq commutes with other operations on environments.
Parameter eq_get : forall E F,
  E F ->
  forall x, get x E = get x F.
Parameter eq_get_inv : forall E F,
  (forall x, get x E = get x F) ->
  E F.
Parameter eq_map : forall f E F,
  E F ->
  map f E map f F.
Parameter eq_map_inv : forall f E F,
  Image.injective A B f ->
  map f E map f F ->
  E F.
Parameter eq_remove : forall x E F,
  ok E -> ok F ->
  E F ->
  E {x} F {x}.
Parameter eq_all_remove : forall xs E F,
  ok E -> ok F ->
  E F ->
  E xs F xs.
Parameter eq_update : forall E F G,
  E F ->
  (E ::= G) (F ::= G).
Parameter eq_belongs : forall x E F,
  E F ->
  x E ->
  x F.
Parameter eq_all_belongs : forall xs E F,
  E F ->
  xs E ->
  xs F.
Parameter eq_notin : forall x E F,
  E F ->
  x E ->
  x F.
Parameter eq_all_notin : forall xs E F,
  E F ->
  xs E ->
  xs F.

Decidability of eq.
Parameter eq_dec : forall E F,
  (forall w w', { w = w' } + { ¬ w = w' }) ->
  ok E -> ok F ->
  { E F } + { ¬ E F }.

Additional principal properties


Parameter update_is_remove_concat : forall x v E,
  x E ->
  E ::= (x v) (E {x}) & (x v).

End Properties.

End Generic_Env_Type.