Information Technology Reference
In-Depth Information
as the remaining arguments; axioms for
others
are less restrictive, allowing them to be
expressed in terms of their application to
constructors
or variables as first argument and
without restriction for the remaining arguments.
Because operations can be partial, specifications also define the
domain condition
of every partial operation, i.e, the situations in which the operation is required to be
defined. For instance, in
ListWM
,
get
is declared to be partial (as indicated by the
partial arrow
-->?
) and its domain condition defines that
get(L
,
I)
must be defined if
I
is indeed an index of list
L
.
As shown in Figure 1, specifications are put together using
specifications modules
.
Specifications identified as
core
define the data types that need to be implemented while
theroleof
parameter
specifications is simply to impose constraints over their admissi-
ble instantiations. Now, suppose we have a candidate implementation for module
LWM
and that we would like to check its conformance against what was specified. First we
need to establish a correspondence between each core sort
s
of the module
LWM
and
aJavatype
T
defined by one of our classes. Moreover, we need to establish a corre-
spondence between the operations and predicates of the specification that introduces
s
and the methods and constructors of
T
.InC
ON
G
U
, this correspondence is defined by
means of a
refinement mapping
. In order to capture the role of parameter specifications,
these mappings also allow to link parameter specifications with the type variables of
generic classes. More concretely, a refinement mapping also defines a correspondence
between each parameter sort
s
and a Java type variable
E
and also a method signature
for each operation/predicate of the specification that introduces
s
.
Suppose that our candidate implementation for
LWM
consists of the generic class
MyListWMerge
and the generic interface
Mergeable
presented in Figure 2. The cor-
respondence between
LWM
and this candidate implementation is defined in the refine-
ment mapping presented in Figure 3. It maps the compound sort
ListWM[Mergeable]
(Figure 1) into the generic type
MyListWMerge<E
extends
Mergeable<E>>
(Fig-
ure 2) and the operations and predicates of the former into methods and constructors
of the latter. For instance, we can see that operation
add
is mapped into the method
void
addFirst(E e)
. The first argument of an operation always correspond to ob-
ject
this
and, hence, an operation with
n
arguments is mapped into a method with arity
n
. Only operations declared
constructors
whose first argument is not the sort being
specified can be mapped into class constructors. Predicates are necessarily mapped into
boolean methods. For operations that produce elements of the sort being specified, the
corresponding method can either be
void
or of the corresponding type. In this way,
it is possible to deal with different implementation styles, namely immutable and mu-
table implementations. In our example, the class
MyListWMerge
provides a mutable
implementation of lists and, hence, all operations in this situation are mapped to
void
methods.
The mapping in Figure 3 also establishes a correspondence between sort
Mergeable
and thetype variable
E
. It is defined that the operation
merge
corresponds to the method
signature
E merge(E e)
. As we will explain in the next section, this refinement map-
ping is only correct if the instantiation of
E
in
MyListWMerge<E>
is limited to classes
C
that have a method with signature
C merge(C e)
(which is indeed the case because
E
has
Mergeable<E>
as an upper bound).
−
1
Search WWH ::
Custom Search