Library CoreGenericEnv
Require Import Equalities.
Module Type CoreGenericEnvironmentType (VarType : UsualDecidableType).
Require Import List.
Import VarType.
Definition TVar := VarType.t.
gen_env A is an environment that binds variables to values of type A.
The decidability of equality on keys (variables) is imported from Var.
Empty environment.
Environment build upon explicit associations.
Concatenation of environment (the second one binds first).
The main operation on environment, get the type of a variable.
Domain and image of an environment.
Check the occurence of variable(s) in an environment.
Check the non-occurence of variable(s) in an environment.
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.
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.
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.
| 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.
xs ∷ vs is the notation for an environment mapping xs to vs.
E & F is the notation for concatenation of E and F.
E ∖ { x } is the notation for removing x from E.
E ∖ xs is the notation for removing xs from E.
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.
x ∈ E to be read x is bound in E.
xs ⊂ E to be read xs are bound in E.
x '∉' E to be read x is unbound in E.
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.
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).
(P (@empty A)) ->
(forall (E : gen_env A) x (v : A), P E -> P (E & (x ∶ v))) ->
(forall (E : gen_env A), P E).
Environment built from lists.
Axiom singles_empty : forall A,
nil ∷ nil = (@empty A).
Axiom singles_cons : forall A x xs (v : A) (vs : list A),
(x :: xs) ∷ (v :: vs) = (xs ∷ vs) & (x ∶ v).
nil ∷ nil = (@empty A).
Axiom singles_cons : forall A x xs (v : A) (vs : list A),
(x :: xs) ∷ (v :: vs) = (xs ∷ vs) & (x ∶ v).
Concatenation admits empty as neutral element, and is associative.
Axiom concat_empty_r : forall A (E : gen_env A),
E & (@empty A) = E.
Axiom concat_empty_l : forall A (E : gen_env A),
(@empty A) & E = E.
Axiom concat_assoc : forall A (E F G : gen_env A),
E & (F & G) = (E & F) & G.
E & (@empty A) = E.
Axiom concat_empty_l : forall A (E : gen_env A),
(@empty A) & E = E.
Axiom concat_assoc : forall A (E F G : gen_env A),
E & (F & G) = (E & F) & G.
Get is None on empty.
Get is Some when it binds.
Axiom get_single_eq : forall A x y (v : A),
x = y ->
get x (y ∶ v) = Some v.
Axiom get_single_eq_inv : forall A x y (v w : A),
get x (y ∶ w) = Some v ->
x = y /\ v = w.
x = y ->
get x (y ∶ v) = Some v.
Axiom get_single_eq_inv : forall A x y (v w : A),
get x (y ∶ w) = Some v ->
x = y /\ v = w.
Get is decidable.
Get and concatenation.
Axiom get_concat_r : forall A x y (v : A) (E : gen_env A),
x = y ->
get x (E & (y ∶ v)) = Some v.
Axiom get_concat_l : forall A x y (v : A) (E : gen_env A),
x <> y ->
get x (E & (y ∶ v)) = get x E.
Axiom get_concat_inv : forall A x y (v w : A) (E : gen_env A),
get x (E & (y ∶ v)) = Some w ->
(x = y /\ v = w) \/ (x <> y /\ get x E = Some w).
x = y ->
get x (E & (y ∶ v)) = Some v.
Axiom get_concat_l : forall A x y (v : A) (E : gen_env A),
x <> y ->
get x (E & (y ∶ v)) = get x E.
Axiom get_concat_inv : forall A x y (v w : A) (E : gen_env A),
get x (E & (y ∶ v)) = Some w ->
(x = y /\ v = w) \/ (x <> y /\ get x E = Some w).
Dom builds a list.
Axiom dom_empty : forall A,
dom (@empty A) = nil.
Axiom dom_empty_inv : forall A (E : gen_env A),
dom (E) = nil ->
E = (@empty A).
Axiom dom_single : forall A x (v : A),
dom (x ∶ v) = (x :: nil).
Axiom dom_singles : forall A xs (vs : list A),
length xs = length vs ->
dom (xs ∷ vs) = xs.
Axiom dom_singles_incl : forall A xs (vs : list A),
List.incl (dom (xs ∷ vs)) xs.
Axiom dom_concat : forall A (E F : gen_env A),
dom (E & F) = List.app (dom F) (dom E).
dom (@empty A) = nil.
Axiom dom_empty_inv : forall A (E : gen_env A),
dom (E) = nil ->
E = (@empty A).
Axiom dom_single : forall A x (v : A),
dom (x ∶ v) = (x :: nil).
Axiom dom_singles : forall A xs (vs : list A),
length xs = length vs ->
dom (xs ∷ vs) = xs.
Axiom dom_singles_incl : forall A xs (vs : list A),
List.incl (dom (xs ∷ vs)) xs.
Axiom dom_concat : forall A (E F : gen_env A),
dom (E & F) = List.app (dom F) (dom E).
Img builds a list.
Axiom img_empty : forall A,
img (@empty A) = nil.
Axiom img_empty_inv : forall A (E : gen_env A),
img (E) = nil ->
E = (@empty A).
Axiom img_single : forall A x (v : A),
img (x ∶ v) = v :: nil.
Axiom img_singles : forall A xs (vs : list A),
length xs = length vs ->
img (xs ∷ vs) = vs.
Axiom img_singles_incl : forall A xs (vs : list A),
List.incl (img (xs ∷ vs)) vs.
Axiom img_concat : forall A (E F : gen_env A),
img (E & F) = List.app (img F) (img E).
img (@empty A) = nil.
Axiom img_empty_inv : forall A (E : gen_env A),
img (E) = nil ->
E = (@empty A).
Axiom img_single : forall A x (v : A),
img (x ∶ v) = v :: nil.
Axiom img_singles : forall A xs (vs : list A),
length xs = length vs ->
img (xs ∷ vs) = vs.
Axiom img_singles_incl : forall A xs (vs : list A),
List.incl (img (xs ∷ vs)) vs.
Axiom img_concat : forall A (E F : gen_env A),
img (E & F) = List.app (img F) (img E).
Dom and img builds identity.
Axiom dom_img_id : forall A (E : gen_env A),
(dom E) ∷ (img E) = E.
Axiom length_dom_img_eq : forall A (E : gen_env A),
length (dom E) = length (img E).
(dom E) ∷ (img E) = E.
Axiom length_dom_img_eq : forall A (E : gen_env A),
length (dom E) = length (img E).
Belongs is false on empty environments.
Belongs in singular(s).
Axiom belongs_single : forall A x y (v : A),
x = y ->
x ∈ (y ∶ v).
Axiom belongs_single_inv : forall A x y (v : A),
x ∈ (y ∶ v) ->
x = y.
Axiom belongs_singles : forall A x xs (vs : list A),
length xs = length vs ->
List.In x xs ->
x ∈ (xs ∷ vs).
Axiom belongs_singles_inv : forall A x xs (vs : list A),
length xs = length vs ->
x ∈ (xs ∷ vs) ->
List.In x xs.
x = y ->
x ∈ (y ∶ v).
Axiom belongs_single_inv : forall A x y (v : A),
x ∈ (y ∶ v) ->
x = y.
Axiom belongs_singles : forall A x xs (vs : list A),
length xs = length vs ->
List.In x xs ->
x ∈ (xs ∷ vs).
Axiom belongs_singles_inv : forall A x xs (vs : list A),
length xs = length vs ->
x ∈ (xs ∷ vs) ->
List.In x xs.
Belongs and concatenation.
Axiom belongs_concat_l : forall A x (F G : gen_env A),
x ∈ F ->
x ∈ (F & G).
Axiom belongs_concat_r : forall A x (F G : gen_env A),
x ∈ F ->
x ∈ (G & F).
Axiom belongs_concat_inv : forall A x (F G : gen_env A),
x ∈ (F & G) ->
x ∈ F ∨ x ∈ G.
x ∈ F ->
x ∈ (F & G).
Axiom belongs_concat_r : forall A x (F G : gen_env A),
x ∈ F ->
x ∈ (G & F).
Axiom belongs_concat_inv : forall A x (F G : gen_env A),
x ∈ (F & G) ->
x ∈ F ∨ x ∈ G.
Belongs and dom.
Axiom belongs_dom : forall A x (E : gen_env A),
x ∈ E ->
List.In x (dom E).
Axiom belongs_dom_inv : forall A x (E : gen_env A),
List.In x (dom E) ->
x ∈ E.
x ∈ E ->
List.In x (dom E).
Axiom belongs_dom_inv : forall A x (E : gen_env A),
List.In x (dom E) ->
x ∈ E.
All_belongs and belongs.
Axiom all_belongs_def : forall A xs (E : gen_env A),
(forall x, List.In x xs -> x ∈ E) ->
xs ⊂ E.
Axiom all_belongs_def_inv : forall A xs (E : gen_env A),
xs ⊂ E ->
(forall x, List.In x xs -> x ∈ E).
Axiom all_belongs_belongs : forall A x xs (E : gen_env A),
(x :: xs) ⊂ E ->
x ∈ E ∧ xs ⊂ E.
Axiom belongs_all_belongs : forall A x xs (E : gen_env A),
x ∈ E ∧ xs ⊂ E ->
(x :: xs) ⊂ E.
(forall x, List.In x xs -> x ∈ E) ->
xs ⊂ E.
Axiom all_belongs_def_inv : forall A xs (E : gen_env A),
xs ⊂ E ->
(forall x, List.In x xs -> x ∈ E).
Axiom all_belongs_belongs : forall A x xs (E : gen_env A),
(x :: xs) ⊂ E ->
x ∈ E ∧ xs ⊂ E.
Axiom belongs_all_belongs : forall A x xs (E : gen_env A),
x ∈ E ∧ xs ⊂ E ->
(x :: xs) ⊂ E.
All_belongs is false on empty environments.
Axiom all_belongs_empty : forall A xs,
xs ⊂ (@empty A) ->
xs = nil.
Axiom all_belongs_nil : forall A (E : gen_env A),
nil ⊂ E.
xs ⊂ (@empty A) ->
xs = nil.
Axiom all_belongs_nil : forall A (E : gen_env A),
nil ⊂ E.
All_belongs in singular(s).
Axiom all_belongs_single : forall A xs y (v : A),
xs = y :: nil ->
xs ⊂ (y ∶ v).
Axiom all_belongs_single_inv : forall A xs y (v : A),
length xs = 1 ->
xs ⊂ (y ∶ v) ->
xs = y :: nil.
Axiom all_belongs_singles : forall A xs ys (vs : list A),
length ys = length vs ->
List.incl xs ys ->
xs ⊂ (ys ∷ vs).
Axiom all_belongs_singles_inv : forall A xs ys (vs : list A),
xs ⊂ (ys ∷ vs) ->
List.incl xs ys.
xs = y :: nil ->
xs ⊂ (y ∶ v).
Axiom all_belongs_single_inv : forall A xs y (v : A),
length xs = 1 ->
xs ⊂ (y ∶ v) ->
xs = y :: nil.
Axiom all_belongs_singles : forall A xs ys (vs : list A),
length ys = length vs ->
List.incl xs ys ->
xs ⊂ (ys ∷ vs).
Axiom all_belongs_singles_inv : forall A xs ys (vs : list A),
xs ⊂ (ys ∷ vs) ->
List.incl xs ys.
All_belongs and concatenation.
Axiom all_belongs_concat_l : forall A xs (F G : gen_env A),
xs ⊂ F ->
xs ⊂ (F & G).
Axiom all_belongs_concat_r : forall A xs (F G : gen_env A),
xs ⊂ F ->
xs ⊂ (G & F).
xs ⊂ F ->
xs ⊂ (F & G).
Axiom all_belongs_concat_r : forall A xs (F G : gen_env A),
xs ⊂ F ->
xs ⊂ (G & F).
All_belongs and dom.
Axiom all_belongs_dom : forall A xs (E : gen_env A),
xs ⊂ E ->
List.incl xs (dom E).
Axiom all_belongs_dom_inv : forall A xs (E F : gen_env A),
List.incl xs (dom E) ->
xs ⊂ E.
xs ⊂ E ->
List.incl xs (dom E).
Axiom all_belongs_dom_inv : forall A xs (E F : gen_env A),
List.incl xs (dom E) ->
xs ⊂ E.
Notin and belongs.
Axiom notin_belongs : forall A x (E : gen_env A),
x ∉ E ->
¬ x ∈ E.
Axiom belongs_notin : forall A x (E : gen_env A),
x ∈ E ->
¬ x ∉ E.
Axiom not_belongs_notin : forall A x (E : gen_env A),
¬ x ∈ E ->
x ∉ E.
Axiom notin_belongs_neq : forall A x y (E : gen_env A),
x ∈ E -> y ∉ E ->
x <> y.
x ∉ E ->
¬ x ∈ E.
Axiom belongs_notin : forall A x (E : gen_env A),
x ∈ E ->
¬ x ∉ E.
Axiom not_belongs_notin : forall A x (E : gen_env A),
¬ x ∈ E ->
x ∉ E.
Axiom notin_belongs_neq : forall A x y (E : gen_env A),
x ∈ E -> y ∉ E ->
x <> y.
Notin is true on empty environments.
Notin in singular(s).
Axiom notin_single : forall A x y (v : A),
x <> y ->
x ∉ (y ∶ v).
Axiom notin_single_inv : forall A x y (v : A),
x ∉ (y ∶ v) ->
x <> y.
Axiom notin_singles : forall A x xs (vs : list A),
¬ List.In x xs ->
x ∉ (xs ∷ vs).
Axiom notin_singles_inv : forall A x xs (vs : list A),
length xs = length vs ->
x ∉ (xs ∷ vs) ->
¬ List.In x xs.
x <> y ->
x ∉ (y ∶ v).
Axiom notin_single_inv : forall A x y (v : A),
x ∉ (y ∶ v) ->
x <> y.
Axiom notin_singles : forall A x xs (vs : list A),
¬ List.In x xs ->
x ∉ (xs ∷ vs).
Axiom notin_singles_inv : forall A x xs (vs : list A),
length xs = length vs ->
x ∉ (xs ∷ vs) ->
¬ List.In x xs.
Notin and concatenation.
Axiom notin_concat : forall A x (F G : gen_env A),
x ∉ F -> x ∉ G ->
x ∉ (F & G).
Axiom notin_concat_inv : forall A x (F G : gen_env A),
x ∉ (F & G) ->
x ∉ F ∧ x ∉ G.
x ∉ F -> x ∉ G ->
x ∉ (F & G).
Axiom notin_concat_inv : forall A x (F G : gen_env A),
x ∉ (F & G) ->
x ∉ F ∧ x ∉ G.
Notin and dom.
Axiom notin_dom : forall A x (E : gen_env A),
x ∉ E ->
¬ List.In x (dom E).
Axiom notin_dom_inv : forall A x (E F : gen_env A),
¬ List.In x (dom E) ->
x ∉ E.
x ∉ E ->
¬ List.In x (dom E).
Axiom notin_dom_inv : forall A x (E F : gen_env A),
¬ List.In x (dom E) ->
x ∉ E.
All_notin is true on empty lists.
All_notin and notin.
Axiom all_notin_def : forall A xs (E : gen_env A),
(forall x, List.In x xs -> x ∉ E) ->
xs ⊄ E.
Axiom all_notin_def_inv : forall A xs (E : gen_env A),
xs ⊄ E ->
(forall x, List.In x xs -> x ∉ E).
Axiom all_notin_notin : forall A x xs (E : gen_env A),
(x :: xs) ⊄ E ->
x ∉ E ∧ xs ⊄ E.
Axiom notin_all_notin : forall A x xs (E : gen_env A),
x ∉ E ∧ xs ⊄ E ->
(x :: xs) ⊄ E.
(forall x, List.In x xs -> x ∉ E) ->
xs ⊄ E.
Axiom all_notin_def_inv : forall A xs (E : gen_env A),
xs ⊄ E ->
(forall x, List.In x xs -> x ∉ E).
Axiom all_notin_notin : forall A x xs (E : gen_env A),
(x :: xs) ⊄ E ->
x ∉ E ∧ xs ⊄ E.
Axiom notin_all_notin : forall A x xs (E : gen_env A),
x ∉ E ∧ xs ⊄ E ->
(x :: xs) ⊄ E.
All_notin and belongs.
All_notin is true on empty environments.
All_notin in singular(s).
Axiom all_notin_single : forall A xs y (v : A),
¬ List.In y xs ->
xs ⊄ (y ∶ v).
Axiom all_notin_single_inv : forall A xs y (v : A),
xs ⊄ (y ∶ v) ->
¬ List.In y xs.
Axiom all_notin_singles : forall A xs ys (vs : list A),
List.Forall (fun x => ¬ List.In x ys) xs ->
xs ⊄ (ys ∷ vs).
Axiom all_notin_singles_inv : forall A xs ys (vs : list A),
length ys = length vs ->
xs ⊄ (ys ∷ vs) ->
List.Forall (fun x => ¬ List.In x ys) xs.
¬ List.In y xs ->
xs ⊄ (y ∶ v).
Axiom all_notin_single_inv : forall A xs y (v : A),
xs ⊄ (y ∶ v) ->
¬ List.In y xs.
Axiom all_notin_singles : forall A xs ys (vs : list A),
List.Forall (fun x => ¬ List.In x ys) xs ->
xs ⊄ (ys ∷ vs).
Axiom all_notin_singles_inv : forall A xs ys (vs : list A),
length ys = length vs ->
xs ⊄ (ys ∷ vs) ->
List.Forall (fun x => ¬ List.In x ys) xs.
All_notin and concatenation.
Axiom all_notin_concat : forall A xs (F G : gen_env A),
xs ⊄ F -> xs ⊄ G ->
xs ⊄ (F & G).
Axiom all_notin_concat_inv : forall A xs (F G : gen_env A),
xs ⊄ (F & G) ->
xs ⊄ F ∧ xs ⊄ G.
xs ⊄ F -> xs ⊄ G ->
xs ⊄ (F & G).
Axiom all_notin_concat_inv : forall A xs (F G : gen_env A),
xs ⊄ (F & G) ->
xs ⊄ F ∧ xs ⊄ G.
All_notin and dom.
Axiom all_notin_dom : forall A xs (E : gen_env A),
xs ⊄ E ->
List.Forall (fun x => ¬ List.In x (dom E)) xs.
Axiom all_notin_dom_inv : forall A xs (E : gen_env A),
List.Forall (fun x => ¬ List.In x (dom E)) xs ->
xs ⊄ E.
xs ⊄ E ->
List.Forall (fun x => ¬ List.In x (dom E)) xs.
Axiom all_notin_dom_inv : forall A xs (E : gen_env A),
List.Forall (fun x => ¬ List.In x (dom E)) xs ->
xs ⊄ E.
Map is applied on type(s).
Axiom map_empty : forall A B (f : A -> B),
map f (@empty A) = (@empty B).
Axiom map_single : forall A B (f : A -> B) x (v : A),
map f (x ∶ v) = x ∶ (f v).
Axiom map_singles : forall A B (f : A -> B) xs (vs : list A),
map f (xs ∷ vs) = xs ∷ (List.map f vs).
map f (@empty A) = (@empty B).
Axiom map_single : forall A B (f : A -> B) x (v : A),
map f (x ∶ v) = x ∶ (f v).
Axiom map_singles : forall A B (f : A -> B) xs (vs : list A),
map f (xs ∷ vs) = xs ∷ (List.map f vs).
Map commutes with concatenation.
Axiom map_concat : forall A B (f : A -> B) (E F : gen_env A),
map f (E & F) = (map f E) & (map f F).
map f (E & F) = (map f E) & (map f F).
Dom is unchanged by map.
Belongs commutes with map.
Axiom belongs_map : forall A B x (E : gen_env A) (f : A -> B),
x ∈ E ->
x ∈ (map f E).
Axiom belongs_map_inv : forall A B x (E : gen_env A) (f : A -> B),
x ∈ (map f E) ->
x ∈ E.
x ∈ E ->
x ∈ (map f E).
Axiom belongs_map_inv : forall A B x (E : gen_env A) (f : A -> B),
x ∈ (map f E) ->
x ∈ E.
All_belongs commutes with map.
Axiom all_belongs_map : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊂ E ->
xs ⊂ (map f E).
Axiom all_belongs_map_inv : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊂ (map f E) ->
xs ⊂ E.
xs ⊂ E ->
xs ⊂ (map f E).
Axiom all_belongs_map_inv : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊂ (map f E) ->
xs ⊂ E.
Notin commutes with map.
Axiom notin_map : forall A B x (E : gen_env A) (f : A -> B),
x ∉ E ->
x ∉ (map f E).
Axiom notin_map_inv : forall A B x (E : gen_env A) (f : A -> B),
x ∉ (map f E) ->
x ∉ E.
x ∉ E ->
x ∉ (map f E).
Axiom notin_map_inv : forall A B x (E : gen_env A) (f : A -> B),
x ∉ (map f E) ->
x ∉ E.
All_notin commutes with map.
Axiom all_notin_map : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊄ E ->
xs ⊄ (map f E).
Axiom all_notin_map_inv : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊄ (map f E) ->
xs ⊄ E.
xs ⊄ E ->
xs ⊄ (map f E).
Axiom all_notin_map_inv : forall A B xs (E : gen_env A) (f : A -> B),
xs ⊄ (map f E) ->
xs ⊄ E.
Ok commutes with map.
Axiom ok_map : forall A B (E : gen_env A) (f : A -> B),
ok E ->
ok (map f E).
Axiom ok_map_inv : forall A B (E : gen_env A) (f : A -> B),
ok (map f E) ->
ok E.
ok E ->
ok (map f E).
Axiom ok_map_inv : forall A B (E : gen_env A) (f : A -> B),
ok (map f E) ->
ok E.
Update_one is identity on empty environments.
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).
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.
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.
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.
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.
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.
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.
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.
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].
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.
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.
Update is identity in presence of empty environments.
Axiom update_empty_r : forall A (E : gen_env A),
E ::= (@empty A) = E.
Axiom update_empty_l : forall A (E : gen_env A),
(@empty A) ::= E = (@empty A).
E ::= (@empty A) = E.
Axiom update_empty_l : forall A (E : gen_env A),
(@empty A) ::= E = (@empty A).
Update with single.
Axiom update_update_one : forall A x (v : A) (E : gen_env A),
E ::= (x ∶ v) = E [x <- v].
Axiom update_single_single : forall A x y (v w : A),
x = y ->
(x ∶ v) ::= (y ∶ w) = (x ∶ w).
Axiom update_single_single_neq : forall A x y (v w : A),
x <> y ->
(x ∶ v) ::= (y ∶ w) = (x ∶ v).
E ::= (x ∶ v) = E [x <- v].
Axiom update_single_single : forall A x y (v w : A),
x = y ->
(x ∶ v) ::= (y ∶ w) = (x ∶ w).
Axiom update_single_single_neq : forall A x y (v w : A),
x <> y ->
(x ∶ v) ::= (y ∶ w) = (x ∶ v).
Update commutes with concatenation on the right.
Dom is unchanged by updating.
Belongs commutes with update.
Axiom belongs_update : forall A x (E F : gen_env A),
x ∈ E ->
x ∈ (E ::= F).
Axiom belongs_update_inv : forall A x (E F : gen_env A),
x ∈ (E ::= F) ->
x ∈ E.
x ∈ E ->
x ∈ (E ::= F).
Axiom belongs_update_inv : forall A x (E F : gen_env A),
x ∈ (E ::= F) ->
x ∈ E.
All_belongs commutes with update.
Axiom all_belongs_update : forall A xs (E F : gen_env A),
xs ⊂ E ->
xs ⊂ (E ::= F).
Axiom all_belongs_update_inv : forall A xs (E F : gen_env A),
xs ⊂ (E ::= F) ->
xs ⊂ E.
xs ⊂ E ->
xs ⊂ (E ::= F).
Axiom all_belongs_update_inv : forall A xs (E F : gen_env A),
xs ⊂ (E ::= F) ->
xs ⊂ E.
Notin commutes with update.
Axiom notin_update : forall A x (E F : gen_env A),
x ∉ E ->
x ∉ (E ::= F).
Axiom notin_update_inv : forall A x (E F : gen_env A),
x ∉ (E ::= F) ->
x ∉ E.
x ∉ E ->
x ∉ (E ::= F).
Axiom notin_update_inv : forall A x (E F : gen_env A),
x ∉ (E ::= F) ->
x ∉ E.
All_notin commutes with update.
Axiom all_notin_update : forall A xs (E F : gen_env A),
xs ⊄ E ->
xs ⊄ (E ::= F).
Axiom all_notin_update_inv : forall A xs (E F : gen_env A),
xs ⊄ (E ::= F) ->
xs ⊄ E.
xs ⊄ E ->
xs ⊄ (E ::= F).
Axiom all_notin_update_inv : forall A xs (E F : gen_env A),
xs ⊄ (E ::= F) ->
xs ⊄ E.
Update is identity when the domains are disjoints.
Update commutes with map.
Axiom map_update : forall A B (f : A -> B) (E F : gen_env A),
map f (E ::= F) = (map f E) ::= (map f F).
map f (E ::= F) = (map f E) ::= (map f F).
Ok commutes with update.
Axiom ok_update : forall A (E F : gen_env A),
ok E ->
ok (E ::= F).
Axiom ok_update_inv : forall A (E F : gen_env A),
ok (E ::= F) ->
ok E.
ok E ->
ok (E ::= F).
Axiom ok_update_inv : forall A (E F : gen_env A),
ok (E ::= F) ->
ok E.
Remove is identity on empty environments.
Remove on singular.
Axiom remove_single_eq : forall A x y (v : A),
x = y ->
(x ∶ v) ∖ {y} = (@empty A).
Axiom remove_single_neq : forall A x y (v : A),
x <> y ->
(x ∶ v) ∖ {y} = (x ∶ v).
x = y ->
(x ∶ v) ∖ {y} = (@empty A).
Axiom remove_single_neq : forall A x y (v : A),
x <> y ->
(x ∶ v) ∖ {y} = (x ∶ v).
Remove and notin and belongs.
Axiom remove_notin : forall A x (E : gen_env A),
x ∉ E ->
E ∖ {x} = E.
Axiom notin_remove_notin : forall A x y (E : gen_env A),
x ∉ E ->
x ∉ (E ∖ {y}).
Axiom all_notin_remove_notin : forall A xs y (E : gen_env A),
xs ⊄ E ->
xs ⊄ (E ∖ {y}).
Axiom belongs_remove : forall A x y (E : gen_env A),
x <> y -> x ∈ E ->
x ∈ (E ∖ {y}).
Axiom belongs_remove_inv : forall A x y (E : gen_env A),
ok E ->
x ∈ (E ∖ {y}) -> x <> y.
x ∉ E ->
E ∖ {x} = E.
Axiom notin_remove_notin : forall A x y (E : gen_env A),
x ∉ E ->
x ∉ (E ∖ {y}).
Axiom all_notin_remove_notin : forall A xs y (E : gen_env A),
xs ⊄ E ->
xs ⊄ (E ∖ {y}).
Axiom belongs_remove : forall A x y (E : gen_env A),
x <> y -> x ∈ E ->
x ∈ (E ∖ {y}).
Axiom belongs_remove_inv : forall A x y (E : gen_env A),
ok E ->
x ∈ (E ∖ {y}) -> x <> y.
Remove and concatenation.
Axiom remove_belongs_concat_r : forall A x (E F : gen_env A),
x ∈ F ->
(E & F) ∖ {x} = E & (F ∖ {x}).
Axiom remove_belongs_concat_l : forall A x (E F : gen_env A),
x ∉ F ->
(E & F) ∖ {x} = (E ∖ {x}) & F.
x ∈ F ->
(E & F) ∖ {x} = E & (F ∖ {x}).
Axiom remove_belongs_concat_l : forall A x (E F : gen_env A),
x ∉ F ->
(E & F) ∖ {x} = (E ∖ {x}) & F.
Remove and belongs and all_belongs.
Axiom remove_ok_notin : forall A x (E : gen_env A),
ok E ->
x ∉ (E ∖ {x}).
Axiom remove_all_belongs : forall A x xs (F : gen_env A),
¬ List.In x xs -> (x :: xs) ⊂ F ->
xs ⊂ (F ∖ {x}).
ok E ->
x ∉ (E ∖ {x}).
Axiom remove_all_belongs : forall A x xs (F : gen_env A),
¬ List.In x xs -> (x :: xs) ⊂ F ->
xs ⊂ (F ∖ {x}).
Remove commutes with map and updating.
Axiom remove_map : forall A B (f : A -> B) (E : gen_env A) x,
(map f E) ∖ {x} = map f (E ∖ {x}).
Axiom remove_update : forall A x (E F : gen_env A),
ok E ->
(E ::= F) ∖ {x} = (E ∖ {x}) ::= F.
Axiom remove_update_eq : forall A x y (v : A) (E : gen_env A),
x = y ->
(E ::= (y ∶ v)) ∖ {x} = E ∖ {x}.
(map f E) ∖ {x} = map f (E ∖ {x}).
Axiom remove_update : forall A x (E F : gen_env A),
ok E ->
(E ::= F) ∖ {x} = (E ∖ {x}) ::= F.
Axiom remove_update_eq : forall A x y (v : A) (E : gen_env A),
x = y ->
(E ::= (y ∶ v)) ∖ {x} = E ∖ {x}.
Ok and remove.
All_remove and remove.
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.
(@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).
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).
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).
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.
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.
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.
(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.
Ok stands for empty and singular environments.
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.
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).
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).
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).
Additional properties when ok stands.
Update commutes with concatenation on the left.