Mefresa.Operation.Compliance

In this section we prove that our operation language complies with the GCM Specification.
We discuss all the auxiliary lemmas that allow us to prove our main theorem stating that provided that our semantic rules are respected, any produced GCM Architecture will indeed meet the GCM Specification.

Meeting the Specification

In the previous sections we mechanized a semantics for an operation language permitting the building of GCM Architectures. Each language constructor was rigorously defined. Moreover, a set of auxiliary lemmas was proved in order to ease our subsequent development.
This section shows that our operation language indeed respects the GCM specification.

Making Components


Lemma valid_mk_comp:
   forall id p ic cl lc li lb (s s':state) ,
    well_formed s ->
    Mk_component id p ic cl lc li lb / s ~~~> Done / s' ->
    well_formed s'.

Proof.

  intros.

  assert ((s->id%comp) = (s'->id%comp) /\
          (s->path%comp) = (s'->path%comp) /\
          (s->iclass%comp) = (s'->iclass%comp) /\
          (s->controlLevel%comp) = (s'->controlLevel%comp) /\
          (s->bindings%comp) = (s'->bindings%comp) /\
          (s->interfaces%comp) = (s'->interfaces%comp)).

    thus eapply root_config_is_unaffected_by_add_comp; eauto.

  destruct s; destruct s'.

  destruct H1 as (Ht1, (Ht2, (Ht3, (Ht4, (Ht5, Ht6)))));
  simpl in *; subst.

  destruct H as (Hi, (Hp, (Hic, (Hc, (Hz, Hw))))); subst.

  firstorder.

  inversion H0; subst; clear H0.

  unfold add_component in H12.


Very well, after the above preliminary machinery we can now start reasoning on how to attack this proof.
First of let us start by showing that the produced component hierarchy l2 originates from adding our component _(Component id t p cl lc li lb)_ to l. This is achieved as follows:
  assert (l2 = (add_component_aux l p (Component id p ic cl lc li lb) )) as Ha.
    destruct (add_component_aux l p (Component id p ic cl lc li lb) );
    inversion H12; auto.


The above as quite easy, let us now prove that the component hierarchy produced by adding a component is always well formed. In this case, we will only need to apply our previously proved lemma well_formed_adding_component and then do some minor footwork.
  assert (well_formed_components (add_component_aux l p (Component id p ic cl lc li lb) )).
    apply well_formed_adding_component;auto.

    Case "Are we inserting in a Well Formed Layer of the Hierarchy?".

      inversion Hw; simpl in *; subst; auto.

      split; auto.


  assert(well_formed_bindings l4 l2 nil).

    apply adding_comp_unaffect_bindings with (p:=p) (lc:=l) (c:=(Component id p ic cl lc li lb));auto.

    subst;auto.


As of now, all the above was pretty much just to "setup the stage", that is, preparing our context for actually proving our lemma. Indeed, we are now in position to prove that after adding a well formed component, in a well formed stated, we will end up in a well formed state.

  destruct (add_component_aux l p (Component id p ic cl lc li lb)); auto.

  Case "Exit Branch 1/2".

    inversion H12.

  Case "Exit Branch 2/2".

    inversion H12; subst.
clear H11 .
    apply WellFormedComponent; intros; simpl in *; auto.

    SCase "Components are Well Formed".

      destruct H1; subst.

      inversion H.

      apply H3.
left; auto.
      inversion H.

      apply H5.
right; auto.
Qed.


Removing Components

Lemma valid_rm_comp:
   forall id p (s s':state) ,
    well_formed s ->
    Rm_component p id / s ~~~> Done / s' ->
    well_formed s'.

Proof.

  intros.

  assert ((s->id%comp) = (s'->id%comp) /\
          (s->path%comp) = (s'->path%comp) /\
          (s->iclass%comp) = (s'->iclass%comp) /\
          (s->controlLevel%comp) = (s'->controlLevel%comp) /\
          (s->bindings%comp) = (s'->bindings%comp) /\
          (s->interfaces%comp) = (s'->interfaces%comp)).

    eapply root_config_is_unaffected_by_remove_comp; eauto.

  destruct s; destruct s'.

  destruct H1 as (Ht1, (Ht2, (Ht3, (Ht4, (Ht5, Ht6)))));
  simpl in *; subst.

  destruct H as (Hi, (Hp, (Hic, (Hc, (Hl, Hw))))); subst.

  firstorder.

  inversion H0; subst; clear H0.

  unfold remove_component in H6.

  inversion H6; subst.
clear H6.
  assert (well_formed_components (remove_component_aux l p id)).

    apply well_formed_removing_component with (p:=p) (id:=id)
          (s:=(Component (Ident "Root") root "null" Configuration l nil l4)); eauto.

    split;auto.

  apply WellFormedComponent; intros; simpl in *; eauto.

Qed.


Making Interfaces


Lemma valid_mk_interfaces:
   forall id t p acc co f ct cd (s s':state) ,
    well_formed s ->
    Mk_interface id t p acc co f ct cd / s ~~~> Done / s' ->
    well_formed s'.

Proof.

  intros.

  assert ((s->id%comp) = (s'->id%comp) /\
          (s->path%comp) = (s'->path%comp) /\
          (s->iclass%comp) = (s'->iclass%comp) /\
          (s->controlLevel%comp) = (s'->controlLevel%comp) /\
          (s->bindings%comp) = (s'->bindings%comp) /\
          (s->interfaces%comp) = (s'->interfaces%comp)).

    thus eapply root_config_is_unaffected_by_add_interface; eauto.

  destruct s; destruct s'.

  destruct H1 as (Ht1, (Ht2, (Ht3, (Ht4, Ht5))));
  simpl in *; subst.

  destruct H as (Hi, (Hp, (Hic, (Hc, (Hl, Hw))))); subst.

  firstorder.

  inversion H0; subst; clear H0.

  unfold add_interface in H14.


As in the lemma valid_mk_comp, we do the above footwork to ease our proof below. Now we can focus on the most relevants aspects, namely the fact that adding a component in the hierarchy always yields a well formed hierarchy. This is achieved by applying a previously proved lemma, and doing some minor steps in order to make our context satisfy the necessary hypotheses.

   assert (well_formed_components (add_interface_aux l p (Interface id t p acc co f ct cd)) ).

     apply well_formed_adding_interface;eauto.

   simpl.

   unfold no_id_acc_clash'; intros;
   unfold no_id_acc_clash in H13.

   apply H13 with (c:=c); auto.

   unfold get_component_with_path.

   destruct p; auto.


As before, we also make this simple assertion just to ease the proof development.
   assert (l2 = add_interface_aux l p (Interface id t p acc co f ct cd) ) as Ha.
    destruct (add_interface_aux l p (Interface id t p acc co f ct cd) );
    inversion H14; auto.


As a last auxiliary step, we ensure that adding an interface does not affect the well formedness of bindings.
    assert(well_formed_bindings l4 l2 nil).
      eapply adding_interface_unaffect_bindings; subst; eauto.


and finnaly, le coup the grace!
   destruct (add_interface_aux l p (Interface id t p acc co f ct cd)).
   Case "1/2".

     congruence.

   Case "2/2".

     inversion H14; subst.
clear H14.
     apply WellFormedComponent; simpl; intros.

     SCase "Well Formed components".

       eauto.

     SCase "Unique Ids".

       inversion H; auto.

     SCase "Well Formed Interfaces".

       apply WellFormedInterfaces_Base;auto.

     SCase "Well Formed Bindings".

       auto.

Qed.


Making Bindings


Lemma valid_mk_bindings:
   forall b (s s':state) ,
    well_formed s ->
    Mk_binding b / s ~~~> Done / s' ->
    well_formed s'.

Proof.

  intros.

  assert ((s->id%comp) = (s'->id%comp) /\
          (s->path%comp) = (s'->path%comp) /\
          (s->iclass%comp) = (s'->iclass%comp) /\
          (s->controlLevel%comp) = (s'->controlLevel%comp) /\
          (s->interfaces%comp) = (s'->interfaces%comp)).

    thus eapply root_config_is_unaffected_by_add_binding; eauto.

  destruct s; destruct s'.

  destruct H1 as (Ht1, (Ht2, (Ht3, (Ht4, Ht5))));
  simpl in *; subst.

  destruct H as (Hi, (Hp, (Hic, (Hc, (Hl, Hw))))); subst.

  firstorder.

  inversion H0; subst; clear H0.

  unfold add_binding in H5.


As in the lemma valid_mk_comp, we do the above footwork to ease our proof below. Now we can focus on the most relevants aspects, namely the fact that adding a binding in the hierarchy always yields a well formed hierarchy. This is achieved by applying a previously proved lemma, and doing some minor steps in order to make our context satisfy the necessary hypotheses.

   assert (well_formed_components (add_binding_aux l (b->path)%bind b)).

    apply well_formed_adding_bindings;auto.

    inversion Hw; simpl in *; subst; auto.

    split; auto.


And now we can prove this lemma! You'll notice that this one requires a little bit more tweaking than its "brothers" above. This should come as no surprise, since it envolves linking components by means of their interfaces.

  inversion H3; simpl in *.

  Case "Path is nil".

    rewrite H0 in H5.

    simpl in H5; inversion H5; subst.

    clear H5.

    apply appending_binding_keeps_component_well_formed; auto.

  Case "Path is not Nil".

    assert (l2 = add_binding_aux l (b ->path)%bind b ).

    destruct H0 as (x, (H1, H2)).

Note that this assertion is only true if path <> nil. Otherwise the binding is inserted at the Root level.
      destruct (add_binding_aux l (b ->path)%bind b ).
      destruct ((b ->path)%bind).

      simpl in H1; inversion H1.

      inversion H5.

      destruct ((b ->path)%bind).

      simpl in H1; inversion H1.

      inversion H5; subst; auto.


As usual, we need to ensure that the bindings remain well formed after adding a binding in the hierarchy.
    assert(well_formed_bindings l4 l2 nil). Focus.
      destruct H0 as (x, (H01, H02)).

      eapply adding_binding_unaffect_bindings; subst; auto.

      SCase "1/3".

        destruct (add_binding_aux l (b ->path)%bind b).

        destruct (b->path%bind).

        inversion H5; subst.
clear H5.
        simpl in H01; inversion H01.

        inversion H5.

        destruct (b->path%bind); inversion H5; subst.

        clear H5.

        simpl in H01; inversion H01.

        clear H5.

        apply Hw.

      SCase "2/3".

       eapply valid_path_fact; eauto.

      SCase "3/3".

        clear -H01.

        unfold get_component_with_path_aux in H01.

        destruct ((b ->path)%bind).

        congruence.
intuition. congruence.
And now, finally, the last steps for victory!
    destruct H0 as (x, (H01, H02)).
    destruct (add_binding_aux l (b ->path)%bind b).

    destruct (b->path%bind).

    unfold get_component_with_path_aux in H01.

    congruence.

    inversion H5.

    destruct (b->path%bind).

    unfold get_component_with_path_aux in H01.

    congruence.

    inversion H5; subst.
clear H5.
    inversion H.

    apply WellFormedComponent; simpl; intros; auto.

Qed.


Removing Bindings


Lemma valid_rm_bindings:
   forall b (s s':state) ,
    well_formed s ->
    Rm_binding b / s ~~~> Done / s' ->
    well_formed s'.

Proof.

  intros.

  assert ((s->id%comp) = (s'->id%comp) /\
          (s->path%comp) = (s'->path%comp) /\
          (s->iclass%comp) = (s'->iclass%comp) /\
          (s->controlLevel%comp) = (s'->controlLevel%comp) /\
          (s->interfaces%comp) = (s'->interfaces%comp)).

    thus eapply root_config_is_unaffected_by_remove_binding; eauto.

  destruct s; destruct s'.

  destruct H1 as (Ht1, (Ht2, (Ht3, (Ht4, Ht5))));
  simpl in *; subst.

  destruct H as (Hi, (Hp, (Hic, (Hc, (Hl, Hw))))); subst.

  firstorder.

  inversion H0; subst; clear H0.

  unfold remove_binding in H4.

   assert (well_formed_components (remove_binding_aux l (b->path)%bind b)).

    apply well_formed_removing_bindings;auto.

    inversion Hw; simpl in *; subst; auto.

    split; auto.

  inversion H3; simpl in *.

  Case "Path is nil".

    rewrite H0 in H4.

    inversion H4; subst.
clear H4.
    functional induction remove_binding_from_list b l1; eauto.

    apply WellFormedComponent; simpl; intros; eauto.

    inversion Hw; simpl in *; auto.

  Case "Path is not Nil".

    destruct H0 as (x, (H01, H02)).

    assert (b->path%bind <> nil).

      destruct (b->path%bind).

      inversion H01.

      discriminate.

    assert (l2 = remove_binding_aux l (b->path%bind) b ).

      destruct (b->path%bind).

      congruence.

      inversion H4; subst; auto.

    assert(well_formed_bindings l1 l2 nil).

      eapply removing_binding_unaffect_bindings; subst; eauto.

      assert (valid_component_path (b->path)%bind ((Component (Ident "Root") root "null" Configuration l nil l4))).

        apply valid_component_binding_has_valid_component_path; auto.

      inversion H4; eauto.

      inversion H3; simpl in *.

      SCase "1/2".

        rewrite H1.

        destruct (remove_binding_aux l (b ->path)%bind b).

        congruence.

        inversion H5; subst.

        congruence.

      SCase "2/2".

        destruct (b->path%bind).

        congruence.

        rewrite <- H1 in H4.

        inversion H4; subst.
clear H4.
        apply WellFormedComponent; simpl; intros; eauto.

Qed.


Hint Resolve valid_mk_bindings valid_mk_interfaces valid_mk_comp
             valid_rm_comp valid_rm_bindings.


Inductive not_sequence a :=
  | IsSeq: forall a1 a2, a = (a1 ; a2) ->
              not_sequence a1 ->
              not_sequence a
  | IsNF : forall a1 a2, a <> (a1; a2) ->
                  not_sequence a.


Function get_left_most a :=
  match a with
  | (a1; a2) => get_left_most a1
  | _ => a
  end.


Lemma get_left_most_fact1:
  forall a a', a' = get_left_most a ->
               forall a1 a2, a' <> (a1;a2).

Proof.

  intros.

  functional induction get_left_most a.

  apply IHo; auto.

  destruct a'; try discriminate.

  inversion y.

Qed.


Lemma get_left_most_fact2:
   forall a s a' s',
          a / s ~~~> a' / s' ->
          get_left_most a / s ~~~> Done / s'.

Proof.

  induction a; intros; try thus inversion H; subst; auto.

  inversion H; subst.

  Case "1/3".

    simpl.

    eapply IHa1; eauto.

  Case "2/3: SeqFinish".

    simpl; auto.

  Case "3/3".

    clear IHa2.

    simpl.

    eapply IHa1; eauto.

Qed.


Lemma valid_seq_aux:
   forall x,
    well_formed (snd x) ->
    forall y, step x y ->
    forall a1 a2, fst x = (a1; a2) ->
    well_formed (snd y).

Proof.

  intros.

  inversion H0.

  Case "Composition #1".
Focus.
    destruct x; destruct y.

    inversion H3; subst.

    simpl in *.

    inversion H1.
subst.
    clear H3 H1.

    inversion H4; subst.

    clear H4.

    apply get_left_most_fact2 in H0.

    assert (forall a a', get_left_most (a1; a2) <> (a; a')).

      intro; eapply get_left_most_fact1; auto.

    destruct (get_left_most (a1; a2));
    try thus inversion H0; subst; eauto.

    intuition.

    assert (False).

      eapply H1; auto.

    inversion H3.

     simpl.

  Case "Composition #2".

    destruct x; destruct y.

    simpl in *; subst; auto.

    inversion H3; subst.

    inversion H2; subst.

    clear H3 H2.
auto.
  Case "Composition #3".

    destruct x; destruct y.

    simpl in *; subst; auto.

    inversion H3; subst.

    inversion H4; subst.

    clear H4 H3.

    induction a1; subst; eauto; try thus inversion H2; subst; auto.

  Case "Done Refl".

    simpl; subst; auto.

  Case "Mk Component".

    simpl; subst; eauto.

  Case "Rm Component".

    simpl; subst; eauto.

  Case "Mk Interface".

    simpl; subst; eauto.

  Case "Mk Binding".

    simpl; subst; eauto.

  Case "Rm Binding".

    simpl; subst; eauto.

Qed.


Lemma valid_seq:
   forall a1 a2 (s s':state) ,
    well_formed s ->
    forall a', (a1; a2) / s ~~~> a' / s' ->
    well_formed s'.

Proof.

  intros.

  assert (well_formed(snd(a', s'))).

   apply valid_seq_aux with (x:=((a1;a2), s)) (a1:=a1) (a2:=a2);
   simpl; auto.

  simpl in H1; auto.

Qed.


Hint Resolve valid_seq .


Theorem seq_validity :
  forall x,
  well_formed (snd x) ->
  forall y, refl_step_closure step x y ->
  fst y = Done ->
  forall a1 a2, fst x = (a1; a2) ->
  well_formed (snd y).

Proof.

  intros.

  destruct x.

  simpl in H2; subst.

  destruct y.

  induction H0.

  Case "Refl".

    auto.

  Case "At Least One Step".

    apply IHrefl_step_closure; auto.

    clear IHrefl_step_closure.

    destruct x as (x, sx); destruct y as (y, sy).

    simpl in *.

    inversion H0; subst;
    [ eapply valid_seq; eauto
    | eapply valid_seq; eauto
    | eapply valid_seq; eauto
    | auto
    | eapply valid_mk_comp; eauto
    | eapply valid_rm_comp; eauto
    | eapply valid_mk_interfaces; eauto
    | eapply valid_mk_bindings; eauto
    | eapply valid_rm_bindings; eauto ].

Qed.


Hint Resolve seq_validity.


Theorem validity :
  forall s,
  well_formed s ->
  forall a s', a / s ~~~>* Done / s' ->
  well_formed s'.

Proof.

  intros.

  inversion H0.

  Case "One Step".

    inversion H0; subst; eauto; try congruence.

  Case "At Least One Step".

  destruct a;
  [ inversion H0;
    apply valid_mk_comp with (id:=i) (p:=p) (ic:=i0) (cl:=c) (lc:=l) (li:=l0) (lb:=l1) (s:=s); auto;
    inversion H4; subst;
    inversion H5; subst;auto;
    apply done_is_quiet in H5; subst; auto
  
  | inversion H0;
    apply valid_rm_comp with (id:=i) (p:=p) (s:=s);
    eauto; inversion H4; subst;
    inversion H5; subst;auto;
    apply done_is_quiet in H5; subst; auto
  
  | inversion H0;
    apply valid_mk_interfaces with (id:=i) (t:=s0) (p:=p) (acc:=v) (co:=r) (f:=f) (ct:=c) (cd:=c0) (s:=s); auto;
    inversion H4; subst;
    inversion H5; subst;auto;
    apply done_is_quiet in H5; subst; auto
  | inversion H0;
    eapply valid_mk_bindings with (b:=b) (s:=s); eauto;
    inversion H4; subst;
    inversion H5; subst;auto;
    apply done_is_quiet in H5; subst; auto
 
  | inversion H0; apply valid_rm_bindings with (b:=b) (s:=s); eauto;
    inversion H1; subst;
    apply done_is_quiet in H2; subst; auto
   
  |
  |
   ].


  assert (well_formed (snd (Done, s'))).

    apply seq_validity with (x:= ((a1;a2),s)) (a1:=a1) (a2:=a2); auto.

  simpl in H3; auto.

  apply done_is_quiet in H0; subst; auto.

Qed.


In this section we prove that our operation language complies with the GCM Specification.
We discuss all the auxiliary lemmas that allow us to prove our main theorem stating that provided that our semantic rules are respected, any produced GCM Architecture will indeed meet the GCM Specification.