Mefresa.GCM.CoreElementsFacts
A Few More Words on Interfaces, Bindings and Components
Require Export Mefresa.GCM.Base.
Require Export Mefresa.GCM.Interface.
Require Export Mefresa.GCM.Binding.
Require Export Mefresa.GCM.Component.
Require Export Mefresa.GCM.Examples.
Components will be our first-class citizens. As such it is of our interest to define
several general purpose functions for them.
Function component_interface_id_exists (id:ident) (l:list component) {struct l} : bool :=
match l with
| nil => false
| c :: r => if interface_id_exists id (c->interfaces%comp) then
true
else
component_interface_id_exists id r
end.
Function get_component (id:ident) (l:list component) {struct l}: option component :=
match l with
| nil => None
| e :: r => if (e->id)%comp == id then Some e else get_component id r
end.
Notation "l '[' id ']'" := (get_component id l) (at level 60, right associativity).
Lemma membership_fact:
forall l id c,
l [id] = Some c ->
In c l.
Proof.
intros.
functional induction get_component id l.
Case "1/3".
thus inversion H.
Case "2/3".
inversion H; subst. clear H.
thus left; auto.
Case "3/3".
right.
thus apply IHo; auto.
Qed.
Lemma get_component_correct:
forall l c id,
l [id] = Some c ->
(c ->id)%comp = id.
Proof.
intros.
functional induction get_component id l; auto.
Case "Branch 1/2".
thus inversion H.
Case "Branch 2/2".
thus inversion H; subst; auto.
Qed.
Hint Resolve membership_fact get_component_correct.
Definition get_subComponent (id:ident) (c:component) : option component :=
get_component id (c->subComponents)%comp.
Function remove_component_from_list (id:ident) (l:list component) {struct l}: list component :=
match l with
| nil => nil
| e :: r => if (e->id)%comp == id then
remove_component_from_list id r
else
e :: remove_component_from_list id r
end.
Moreover, since some of our functions return option components, we may need to
compare those as well. As such, we define the following function:
Definition beq_opt_comp opt_comp1 opt_comp2 : bool :=
match opt_comp1, opt_comp2 with
| Some comp1, Some comp2 => beq_ident (comp1->id)%comp (comp2->id)%comp
| _, _ => false
end.
Notation "s1 '==' s2" := (beq_opt_comp s1 s2) (at level 80) : opt_comp_scope.
Notation "s1 '!=' s2" := (~beq_opt_comp s1 s2) (at level 80) : opt_comp_scope.
Bind Scope opt_comp_scope with option component.
Delimit Scope opt_comp_scope with opt_comp.
Inductive not_in_l i l: Prop :=
| NotInNil : l = (nil: list component) ->
not_in_l i l
| NotInStep : forall (a:component) (r:list component),
l = a :: r ->
(((a->id)%comp == i) = false) ->
not_in_l i r ->
not_in_l i l.
Lemma not_in_l_nil:
forall id, not_in_l id nil.
Proof.
intro.
thus apply NotInNil; reflexivity.
Qed.
Hint Resolve not_in_l_nil.
Definition not_in_list (i:ident) (l:list component) : Prop :=
forall e, In e l -> (((e->id)%comp == i) = false).
Lemma same_nots':
forall i l, not_in_list i l -> not_in_l i l.
Proof.
intros.
induction l.
apply NotInNil.
reflexivity.
unfold not_in_list in H.
assert (((a ->id)%comp == i) = false).
apply H with (e:=a); intuition.
apply NotInStep with (a:=a) (r:=l).
reflexivity.
unfold not_in_list in H.
apply H with (e:=a).
intuition.
apply IHl.
unfold not_in_list.
intros.
apply H.
intuition.
Qed.
Lemma same_nots:
forall i l, not_in_l i l -> not_in_list i l.
Proof.
induction 1.
subst.
unfold not_in_list.
intros.
inversion H.
subst.
unfold not_in_list.
intros.
destruct H.
subst.
exact H0.
unfold not_in_list in IHnot_in_l.
apply IHnot_in_l.
exact H.
Qed.
Hint Resolve same_nots same_nots.
Lemma not_in_congruence:
forall c l,
not_in_l (c->id%comp) l ->
In c l ->
False.
Proof.
intros.
apply same_nots in H.
unfold not_in_list in H.
assert (((c ->id)%comp == (c ->id)%comp) = false).
apply H; auto.
assert (((c ->id)%comp <> (c ->id)%comp)).
eauto.
congruence.
Qed.
Inductive unique_ids (l:list component) : Prop :=
| Unique_Base: l = nil -> unique_ids l
| Unique_Step: forall c r,
l = c :: r ->
not_in_l (c->id%comp) r ->
unique_ids r ->
unique_ids l.
Lemma unique_ids_nil:
unique_ids nil.
Proof.
thus apply Unique_Base; reflexivity.
Qed.
Lemma unique_ids_one:
forall x, unique_ids (x :: nil).
Proof.
intros.
eapply Unique_Step; auto.
thus apply unique_ids_nil.
Qed.
Lemma unique_ids_sublist:
forall c r,
unique_ids (c :: r) ->
unique_ids r.
Proof.
intros.
inversion H.
Case "List is nil".
thus inversion H0.
Case "List is not nil".
thus inversion H0; subst; auto.
Qed.
Lemma unique_subset_gen:
forall l1 l2,
unique_ids (app l1 l2) ->
unique_ids l2.
Proof.
intros.
induction l1.
rewrite app_nil_l in H;auto.
apply IHl1.
rewrite <- app_comm_cons in H.
inversion H.
inversion H0.
inversion H0; subst; auto.
Qed.
Lemma unique_subset:
forall c r acc,
unique_ids (app (cons c r) acc) ->
unique_ids (cons c acc).
Proof.
intros.
assert (unique_ids acc).
apply unique_subset_gen with (l1:=c::r);auto.
apply Unique_Step with (c:=c) (r:=acc);auto.
inversion H.
Case "Nil".
inversion H1.
Case "Not Nil".
inversion H1; subst. clear H1.
clear H.
induction r.
SCase "R is Nil".
rewrite app_nil_l in H2; auto.
SCase "R is not Nil".
apply IHr;auto.
inversion H2; inversion H; subst; auto.
inversion H3; inversion H; subst; auto.
Qed.
Lemma unique_ids_fact:
forall c r e,
unique_ids (c :: r) ->
In e r ->
((e->id%comp) == (c->id%comp)) = false.
Proof.
intros.
inversion H; inversion H1; subst. clear H1.
apply same_nots in H2.
unfold not_in_list in H2.
apply H2; auto.
Qed.
Lemma unique_ids_fact':
forall c r,
unique_ids (c :: r) ->
forall c', (c'->id%comp) = (c->id%comp) ->
(~ In c' r).
Proof.
intros.
inversion H; inversion H1; subst. clear H1.
intro.
assert (((c'->id%comp) == (c0->id%comp)) = false).
apply unique_ids_fact with (r:=r0); auto.
assert (((c'->id%comp) == (c0->id%comp)) = true).
auto.
congruence.
Qed.
Definition unique_ids' (l:list component) : Prop :=
forall c c', In c l ->
In c' l ->
((c->id)%comp == (c'->id)%comp) = false.
Lemma same_unique_ids:
forall l,
unique_ids' l ->
unique_ids l.
Proof.
induction l;intros.
Case "l is nil".
apply Unique_Base; reflexivity.
Case "l is not nil".
apply Unique_Step with (c:=a) (r:=l);auto.
unfold unique_ids' in H.
apply same_nots';auto.
unfold not_in_list; intros.
apply H; auto.
right; exact H0.
left; reflexivity.
apply IHl.
unfold unique_ids' in H.
unfold unique_ids'; intros.
apply H.
right; auto.
right; auto.
Qed.
Hint Resolve unique_ids_nil same_unique_ids unique_ids_sublist unique_ids_one.
Function in_l (id:ident) (l:list component) {struct l}: Prop :=
match l with
| nil => False
| c :: r => (c->id)%comp = id \/ in_l id r
end.
Hint Resolve internal_or_external visibility_dec beq_visibility_symmetry
beq_visibility_reflexivity interfaces_fact.