A COO Class:
Extendable Stack
An extendable Stack is bounded as it can store
only SIZE
items. But when it is full
and receives a push
request, it creates an auxiliary Stack, and forwards to it the requests
for the push
and pop services.
Then, this auxiliary Stack is deleted if it becomes empty
after a pop
request. Thus, a Stack acts as if it was unbounded, or the root of a stack
of bounded stacks.
Both the graphical and the textual definition
of this class are shown below.
Class Stack specification;
uses ITEM, Boolean, SIZE;
//C++ items defined in the additional code
operations
unheritable empty () : Boolean
//unheritable operation may access private attributes
begincode return (top == 0) endcode;
services
push (i: ITEM) : <>;
pop () : <ITEM>;
end.
Class Stack implementation;
invokes Stack;
attributes
top : int;
buf : array [SIZE] of ITEM;
aux : Stack*; //a reference toward another Stack
operations
full () : Boolean
begincode return (top == SIZE); endcode;
Init (n : const OCNAME&) //defines the instances’ initial value
begincode setname (n);
top = 0; aux = NULL;endcode;
OBCS //as edited using MACAO
end.
The OBCS of this class features only one place,
the type of which is empty: it may contain only raw tokens bearing no value.
The t1 and
t2 transitions
accept the service push,
and they are guarded by complementary preconditions. t1
stores the item i and returns an acknowledgement, while t2
creates an auxiliary Stack if it does not yet exist, then requests the
push service
of the aux
Stack, and finally returns an acknowledgement. The syntax of the service
call means that no reply is expected for that request, that is t2
sends the acknowledgement without waiting for the result of its request.
Concerning the pop
service, the t5
transition waits for the reply of its request before to send its own reply
to the client.
By default, each service serves requests on
a FIFO policy. To ensure that the pop
service actually returns the last arrived ITEM,
t1 and t2
have an higher priority than t4
and t5.
The t1 and t4 transitions both update the
top attribute,
and thus they cannot occur concurrently, and the same holds for the t2
and t5 transitions w.r.t. the aux
attribute. Since transitions of an OBCS never occur concurrently, this
constraint is automatically enforced and it is pointless to add other places
to ensure their mutual exclusion.
The textual definition of
the class
/* "///" is a shorthand for the begincode and endcode keywords
_S-> is a prefix to acces the Object’s attributes and operations
(it is omitted in the above graphical definition)
*/
Class Stack specification;
uses ITEM, Boolean, SIZE; //C++ types and classes defined by
the designer
operations
unheritable empty () : Boolean
/// return (top == 0) ;///;
services
push (i : ITEM);
pop () : <ITEM>;
end.
Class Stack implementation;
invokes Stack;
attributes
top : int;
rep : array [SIZE] of ITEM;
aux : Stack*; //reference toward another Stack
operations
full () : Boolean
/// return (top == SIZE); ///;
Init (n : const OCNAME&) //defines the instances’ initial value
/// setname (n);
top = 0; aux = NULL;
///;
OBCS
Place p1
type = < >; //the default type
Transition t1
Precond = begincode
!(_S->full())
endcode,
Accept = <i>,
Return = <>,
service = push,
if-added = begincode
printf ("Arrival of a new request for %s\n", _S->_name);
endcode,
Order = begincode
if (t1->c1 < t2->c1) return (1);
else return (0);
endcode,
if-removed = begincode
int i = 1;
endcode,
Action = begincode
_S->rep[_S->top] = i;
_S->top++;
printf("the stack %s is :",_S->_name);
for (int ii=0;ii<_S->top;ii++) {
printf(" %d ",_S->rep[ii]);}
printf("\n");
endcode;
Arcto p1
Valuation = <>; //the default valuation
Transition t2
Precond = begincode
_S->full ()
endcode,
Action = begincode
if (!(_S->aux)){
char* nom=(char *)malloc(10);
gene_nom("pile",nom);
_S->aux= new Stack;
_S->aux->Init (nom);
}
=_S->aux->push (i)
endcode,
Accept = <i>,
Return = <>,
service = push;
Arcto p1;
Transition t5
Precond = begincode
_S->aux!=NULL
endcode,
Accept = <>,
Return = <i>,
service = pop,
Action = begincode
<i> = _S->aux->pop()
if (_S->aux->empty() && _S->aux->codelete==0) {
delete (_S->aux);
_S->aux = NULL;
};
endcode,
trigger = p1;
Arcfrom p1
Valuation = <>;
Transition t4
Precond = begincode
_S->aux==NULL
endcode,
Action = begincode
_S->top --;
i =_S->rep[_S->top];
endcode,
Accept = <>,
Return = <i>,
service = pop,
trigger = p1;
Arcfrom p1
Valuation = <>;
End.
Overview of COOs,
SYROCO
The
Dynamic Philosopher example
Mail to: C.
Sibertin-Blanc