Event Model Decomposition

From Event-B
Jump to navigationJump to search

Introduction

One of the most important feature of the Event-B approach is the ability to introduce new events during refinement steps, but a consequence is an increasing complexity of the refinement process when having to deal with many events and many state variables.

The main idea of the decomposition is to cut a model A into sub-models A_1, ..., A_n, which can be refined separately and more confortably than the whole.

The constraint that shall be satisfied by the decomposition is that these refined models might - the recomposition will never be performed in practice - be recomposed into a whole model C in a way that guarantees that C refines A. An event-based decomposition of a model is detailed in Event Model Decomposition: the events of a model are partitioned to form the events of the sub-models. In parallel, the variables on which these events act are distributed among the sub-models.

The purpose is here to precisely describe what is required at the Rodin platform level to integrate this event model decomposition, and to explain why. The details of how it could be implemented are out of scope.

Terminology

A model can contain contexts, machines, or both. The events are contained in the machines, as well as the variables on which they act, the invariants constraining these variables, and optionnally the variants. The notion of model decomposition is then an extrapolation for the notion of machine decomposition.

  • Shared variable: A variable of a given model which is accessed (read/written) by several distinct events (by opposition to private variable).
  • Private variable: A variable of a given model which is only accessed by an event (by opposition to shared variable).
  • External event: An event of a sub-model simulating the way the read (but not written) variables of a sub-model are handled in the initial model.

Architecture

Specification

High-level requirements

  • Configuring the decomposition
    • Identifying the machine to be decomposed
    • Identifying the sub-machines to be created
    • Specifying how to perform the decomposition (event partition)
    • Asking for simplifications
  • Performing the decomposition
    • Generating the sub-machines
    • Linking the sub-machines to the initial machine
    • Generating the sub-contexts
    • Linking the sub-contexts to the sub-machines
  • Generating the useful proof obligations
  • Not "propagating" useless proof obligations
  • Checking the decomposition

Low-level requirements

About the events

  • Identifying an event as external
  • Generating an external event
    • Generating an external event where the action is deterministic

eg. x,y := x + z,y - x

    • Generating an external event where the action is non-deterministic

eg. x,y :| x' > y \land y' > x' + z or x :\in A \lor {y}

  • Defining an external event as an abstraction of an event of the non-decomposed model that modifies the considered shared variables
  • Ensuring that an external event cannot be refined

About the variables

Some variables are needed by several sub-components of the decomposition. As a consequence, these variables shall be replicated in the sub-components. Beyond that, since it is not possible to ensure that such a variable will be refined in the same way in each sub-component, they shall be given a special status (shared variable), with the limitation that they cannot be refined.

We will specify in this section how to introduce the notion of shared variable in the Rodin platform, and how to check the associated rules.

Defining a variable as shared

The following DTD excerpt describes the structure of a variable in the Rodin database:

<!ENTITY % NameAttDecl "name CDATA #REQUIRED">
<!ENTITY % CommentAttDecl "org.eventb.core.comment CDATA #IMPLIED">
<!ENTITY % IdentAttDecl "org.eventb.core.identifier CDATA #REQUIRED">

<!ELEMENT %variable; EMPTY>
<!ATTLIST %variable;
  %NameAttDecl;
  %CommentAttDecl;
  %IdentAttDecl;
  >

A first possibility to tag a variable as shared would be to add a shared specific attribute, which would be set to true if and only if the variable is shared:

<ENTITY % shared "org.eventb.core.shared CDATA #REQUIRED">

<!ELEMENT %variable; EMPTY>
<!ATTLIST %variable;
  ...
  %shared; (false|true) #REQUIRED
>

Another possibility would be to define a more generic attribute, which could take different values, according to the nature of the variable:

<ENTITY % nature "org.eventb.core.nature CDATA #REQUIRED">

<!ATTLIST %variable;
  ...
  %nature; (0|1) #REQUIRED
>

<!-- The nature attribute encodes the kind of variable:
       0: ordinary variable
       1: shared variable
-->

The second option, which has the main advantage to be more evolutive, is retained here.

Ensuring that a shared variable is not data-refined

A shared variable shall always be present in the state space of any refinement of the component. The verification shall be added to those already performed by the static checker.

Replicating a shared variable in the sub-components of the decomposition

About the invariants

  • Copying an invariant dealing with the private variables of a sub-component in the sub-component
  • Copying an invariant involving a shared variable only in the sub-components where this variable is shared
  • Not copying an invariant related to private and shared variables (?)

About the variants

About the contexts

  • Linking the sub-contexts

Bibliography

  • J.R. Abrial, Mathematical Models for Refinement and Decomposition, in The Event-B Book, to be published in 2009 (lien externe).
  • J.R. Abrial, Event Model Decomposition, Version 1.3, April 2009.
  • M. Butler, Decomposition Structures for Event-B, in Integrated Formal Methods iFM2009, Springer, LNCS 5423, 2009 (lien externe).