Top.Util.Signatures
IMPORTANT
THIS IS A COPY OF THE Environment FILE, RENAMED TO SignaturesOverview
Functions on environments
The domain of an environment is the set of labels that it maps.
Fixpoint dom (E : list (label × A)) : labels :=
match E with
| nil ⇒ empty
| (x, _) :: E' ⇒ union (singleton x) (dom E')
end.
map applies a function to all bindings in the environment.
Fixpoint map (f : A → B) (E : list (label × A)) : list (label × B) :=
match E with
| nil ⇒ nil
| (x, V) :: E' ⇒ (x, f V) :: map f E'
end.
get returns the value bound to the given label in an environment or None if the given label is not bound. If the label has multiple bindings, the one nearest to the head of the environment is returned.
Fixpoint get (x : label) (E : list (label × A)) : option A :=
match E with
| nil ⇒ None
| (y,a) :: E' ⇒ if eq_label_dec x y then Some a else get x E'
end.
End Definitions.
Relations on environments
An environment is well-formed if and only if each label is bound at most once.
Inductive ok : list (label × A) → Prop :=
| ok_nil :
ok nil
| ok_cons : ∀ (E : list (label × A)) (x : label) (a : A),
ok E → ¬ In x (dom E) → ok ((x, a) :: E).
An environment E contains a binding from x to b, denoted (binds x b E), if and only if the most recent binding for x is mapped to b.
Section OpProperties.
Variable A B : Type.
Implicit Types E F : list (label × A).
Implicit Types a b : A.
Lemma concat_nil : ∀ E,
E ++ nil = E.
Lemma nil_concat : ∀ E,
nil ++ E = E.
Lemma concat_assoc : ∀ E F G,
(G ++ F) ++ E = G ++ (F ++ E).
map commutes with environment-building operations
Lemma map_nil : ∀ (f : A → B),
map f nil = nil.
Lemma map_single : ∀ (f : A → B) y b,
map f [(y,b)] = [(y, f b)].
Lemma map_push : ∀ (f : A → B) y b E,
map f ([(y,b)] ++ E) = [(y, f b)] ++ map f E.
Lemma map_concat : ∀ (f : A → B) E F,
map f (F ++ E) = (map f F) ++ (map f E).
Lemma dom_nil :
@dom A nil = empty.
Lemma dom_single : ∀ x a,
dom [(x,a)] = singleton x.
Lemma dom_push : ∀ x a E,
dom ([(x,a)] ++ E) = union (singleton x) (dom E).
Lemma dom_concat : ∀ E F,
dom (F ++ E) = union (dom F) (dom E).
Lemma dom_map : ∀ (f : A → B) E,
dom (map f E) = dom E.
Automation and tactics (I)
simpl_env
Definition singleton_list (A : Type) (x : label × A) := x :: nil.
Lemma cons_concat : ∀ (A : Type) (E : list (label × A)) x a,
(x, a) :: E = singleton_list A (x, a) ++ E.
Lemma map_singleton_list : ∀ (A B : Type) (f : A → B) y b,
map f (singleton_list A (y,b)) = [(y, f b)].
Lemma dom_singleton_list : ∀ (A : Type) (x : label) (a : A),
dom (singleton_list A (x,a)) = singleton x.
Tactic Notation "simpl_env" "in" hyp(H) :=
simpl_env_change_aux;
autorewrite with rew_env in H;
unfold singleton_list in ×.
Tactic Notation "simpl_env" "in" "*" :=
simpl_env_change_aux;
autorewrite with rew_env in *;
unfold singleton_list in ×.
rewrite_env
Tactic Notation "rewrite_env" constr(E) :=
match goal with
| |- context[?x] ⇒
change x with E
| |- context[?x] ⇒
replace x with E; [ | try reflexivity; simpl_env; reflexivity ]
end.
Tactic Notation "rewrite_env" constr(E) "in" hyp(H) :=
match type of H with
| context[?x] ⇒
change x with E in H
| context[?x] ⇒
replace x with E in H; [ | try reflexivity; simpl_env; reflexivity ]
end.
(*
TODO adding this hint globally causes lsetdec to not terminate...
Hint Extern 1 (~ In _ _) => simpl_env in *; lsetdec : core. *)
Section OkProperties.
Variable A B : Type.
Implicit Types E F : list (label × A).
Implicit Types a b : A.
Facts about when an environment is well-formed.
Lemma ok_push : ∀ (E : list (label × A)) (x : label) (a : A),
ok E → ¬ In x (dom E) → ok ([(x, a)] ++ E).
Lemma ok_singleton : ∀ x a,
ok [(x,a)].
Lemma ok_remove_mid : ∀ F E G,
ok (G ++ F ++ E) → ok (G ++ E).
Lemma ok_remove_mid_cons : ∀ x a E G,
ok (G ++ (x, a) :: E) →
ok (G ++ E).
Lemma ok_map : ∀ E (f : A → B),
ok E → ok (map f E).
Lemma ok_map_app_l : ∀ E F (f : A → A),
ok (F ++ E) → ok (map f F ++ E).
A binding in the middle of an environment has an label fresh from all bindings before and after it.
Lemma fresh_mid_tail : ∀ E F x a,
ok (F ++ [(x,a)] ++ E) → ¬ In x (dom E).
Lemma fresh_mid_head : ∀ E F x a,
ok (F ++ [(x,a)] ++ E) → ¬ In x (dom F).
End OkProperties.
Properties of binds
Section BindsProperties.
Variable A B : Type.
Implicit Types E F : list (label × A).
Implicit Types a b : A.
Introduction forms for binds
Lemma binds_singleton : ∀ x a,
binds x a [(x,a)].
Lemma binds_tail : ∀ x a E F,
binds x a E → ¬ In x (dom F) → binds x a (F ++ E).
Lemma binds_head : ∀ x a E F,
binds x a F → binds x a (F ++ E).
Case analysis on binds
Lemma binds_concat_inv : ∀ x a E F,
binds x a (F ++ E) → (¬ In x (dom F) ∧ binds x a E) ∨ (binds x a F).
Lemma binds_singleton_inv : ∀ x y a b,
binds x a [(y,b)] → x = y ∧ a = b.
Lemma binds_mid : ∀ x a E F,
ok (F ++ [(x,a)] ++ E) → binds x a (F ++ [(x,a)] ++ E).
Lemma binds_mid_eq : ∀ z a b E F,
binds z a (F ++ [(z,b)] ++ E) → ok (F ++ [(z,b)] ++ E) → a = b.
Lemma binds_mid_eq_cons : ∀ x a b E F,
binds x a (F ++ (x,b) :: E) →
ok (F ++ (x,b) :: E) →
a = b.
End BindsProperties.
binds_get
binds_cases
Additional properties of binds
Section AdditionalBindsProperties.
Variable A B : Type.
Implicit Types E F : list (label × A).
Implicit Types a b : A.
Lemmas about the relationship between binds and the domain of an environment.
Lemma binds_In : ∀ a x E,
binds x a E → In x (dom E).
Lemma binds_fresh : ∀ x a E,
¬ In x (dom E) → ¬ binds x a E.
Additional lemmas for showing that a binding is in an environment.
Lemma binds_map : ∀ x a (f : A → B) E,
binds x a E → binds x (f a) (map f E).
Lemma binds_concat_ok : ∀ x a E F,
binds x a E → ok (F ++ E) → binds x a (F ++ E).
Lemma binds_weaken : ∀ x a E F G,
binds x a (G ++ E) →
ok (G ++ F ++ E) →
binds x a (G ++ F ++ E).
Lemma binds_weaken_at_head : ∀ x a F G,
binds x a G →
ok (F ++ G) →
binds x a (F ++ G).
Lemma binds_remove_mid : ∀ x y a b F G,
binds x a (F ++ [(y,b)] ++ G) →
x ≠ y →
binds x a (F ++ G).
Lemma binds_remove_mid_cons : ∀ x y a b E G,
binds x a (G ++ (y, b) :: E) →
x ≠ y →
binds x a (G ++ E).
End AdditionalBindsProperties.
(*
Hint Resolve binds_map binds_concat_ok binds_weaken binds_weaken_at_head : core.
Hint Immediate binds_remove_mid binds_remove_mid_cons : core. *)
End Signatures.
Tactic Notation "srewrite_env" constr(E) :=
match goal with
| |- context[?x] ⇒
change x with E
| |- context[?x] ⇒
replace x with E; [ | try reflexivity; Signatures.simpl_env; reflexivity ]
end.
Tactic Notation "srewrite_env" constr(E) "in" hyp(H) :=
match type of H with
| context[?x] ⇒
change x with E in H
| context[?x] ⇒
replace x with E in H; [ | try reflexivity; Signatures.simpl_env; reflexivity ]
end.