• No se han encontrado resultados

ASMedios de acción

6. LA INFRAESTRUCTURA PRODUCTIVA

6.2. PUERTOS Y VÍAS NAVEGABLES

We adopt the approach of Din et al. [DJO05; DDJO12] that transforms class

implementations in α

ABS

to implementations in a simple sequential language

SEQ

enriched with a non-deterministic assignment operator. The

SEQ

language has a well-established semantics and a sound and relatively complete proof sys- tem [Apt81; Apt84]. In this report, the proof system is presented as weakest

liberal preconditions, allowing the class to be compositionally verified method- wise. The soundness of the reasoning of the

SEQ

with the addition of a non- deterministic assignment operator with respect to the operational semantics of

α

ABS

hinges on the fact that there are no shared states between actors[DJO05].

Our presentation of

SEQ

and the encoding follows Din et al.’s[DDJO12].

The following is the syntax for

SEQ

statements.

s::=skip|abort|varv| v := e | s; s |if b{ s }else{ s } |

11.1.

SEQ

language These statements represent the skip, abort, variable declarations, deterministic assignment, sequential composition, conditional, non-deterministic assignment, assert and assume statements, respectively. The abort statement is used to termi- nate the program, usually indicating an error. The skip, variable declaration, de- terministic assignment, sequential composition and conditional statements carry the usual semantics as forα

ABS

. The non-deterministic assignment statement as- signs to the variables v some random values that match the type of the variables. The statementassertbindicates that some required condition b needs to be ver- ified, whereas the statementassume bstates some fact b. Neither statement has any effect, but they are crucial for verifying the desired behavior as we will soon see. The

SEQ

syntax is completed by adding procedure definitions:

PD::= m(x) { T y; s }

A procedure m accepts the parameters x, allows a set of local variables y to be used when executing statement s. The declaration of local variables and the state- ment is called the procedure body. A procedure does not return any value (i.e., it can be seen as aUnitmethod).

SEQ

also contains procedure call statements (x := m(e)). This is omitted from the presentation because the encoding of α

ABS

to

SEQ

does not involve these statements.

To encodeα

ABS

classes in the

SEQ

language, the class attributes f is expanded with the variablethisand the trace variable

t

, representing the self reference and the locally generated trace, respectively. The trace variable allows us to reason about the traces generated by an actor. Because of the focus on the part that is generated by the actor, it is not necessary to include the input events in the trace. They are implicitly represented via the non-deterministic assignments as described below. The fields are also extended when needed by a number of auxil- iary variables ([OG76]) as needed to establish the class invariants. These auxiliary

variables correspond to the internal variables used in the class specification and also extra variables introduced by the encoding. The execution of a task by an ac- tor is represented by a

SEQ

process. A

SEQ

process operates on a state that maps the class attribute variables, the local variables and the auxiliary variables to their corresponding values. The encoding of important parts ofα

ABS

is presented in Figure11.2.

A method definition mtd(p) { body } is translated to the form mtd(p,u) {

 body } where  body  is the encoding of body in

SEQ

. The future in- formation attached with the asynchronous method call is explicitly given in the encoding, allowing their usage when constructing the local trace. When a method call is executed by the actor, the local trace is extended by the corresponding re-

 m(x){ y; s }  def= m(x, fut){ T y,return;

t

:=

t

· fut this: m(x);  s ;

t

:=

t

· fut ←this: m/return;

assumewf(

t

) } skip def= skip

 s1; s2 def =  s1;  s2 ife s1 elses2 def = ife{ s1}else{ s2}  v := e  def= v := e

returne def= return:= e

 v :=newC(e)  def= v0:=some;

t

:=

t

·this→ v0:newC(e); v := v0;

assumewf(

t

)  v1:= v2.m(e) 

def

= u0:=some;

t

:=

t

· u0→ v

2: m(e); v1:= u0;assumewf(

t

) awaitu?v def= assertI(f ,

t

) ∧wf(

t

); f0, t0, v0:=some;

t00:= u ‘ getTgt(

t

, u) : getMtd(

t

, u) / v0;

v:= v0;

t

:=

t

· t0· t00;assumeI(f ,

t

) ∧wf(

t

) awaite def= assertI(f ,

t

) ∧wf(

t

); f0, t0:=some;

t

:=

t

· t0;assumeI(f ,

t

) ∧wf(

t

) ∧ e  v = u.get def= v0:=some;

t

:=

t

· u ‘ getTgt(

t

, u) : getMtd(

t

, u) / v0;

v:= v0;assumewf(

t

) Figure 11.2.: Encoding ofα

ABS

in

SEQ

action event. When the computation is finished, the local trace is extended by the resulting method return event. A class constructor is encoded similarly to a method definition. The main difference is that it does not have the opening call reaction and closing return emittance events.

Statements that do not contribute to the cooperative multitasking aspects (i.e.,

skip, sequential composition, conditional check, variable assignment) have a straightforward translation in

SEQ

. Returns are modeled using the auxiliary vari- ablereturnwhich is assigned to the returned value.

Creating a new actor causes the trace to be extended with the actor creation event. The identity of the new actor is guessed via the non-deterministic assign- ment, and the guess is assumed to be correct by assuming the well-formedness of the trace with respect to the actor this. The well-formedness check is repre- sented bywf(

t

), which is an abbreviation of Definition4.3on well-formed traces of actors, without considering the input events. That is,wf(

t

) only confirms the well-formedness of the generated part of an actor’s trace. A similar approach is

11.1.

SEQ

language

Listing 11.1:Serverencoding in

SEQ

// class Server ()

trace t = [];

// Value serve (Query q) {

Value serve(Query q, Fut<Value> fut) {

IWorker w; Fut<Value> u; Value v; // logical variables trace t0; trace t00; IWorker w’;

Fut<Value> u’;

Value v’;

Value return;

t = t· fut this:serve(q);

// w = new Worker( ) ;

w’ = some;

t = t·this→w0:new Worker(); w = w’; assume wf(t); // u = w.do(q) ; u’ = some; t = t·u0w:do(q); u = u’; assume wf(t); //await u?v ;

assert I(fields, t) && wf(t); t0 = some;

v’ = some;

t00 = u‘ getTgt(t,u) : getMtd(t,u) /v’; v = v’;

t = t·t0·t00;

assume I(fields, t) && wf(t);

//return v ;

return = v;

t = t· fut ←this:serve/return;

assume wf(t); }

also taken to deal with a method call statement, except that the guess is done on the generated future, respectively.

Theawaitandgetstatements are translated in a similar way, except thatawait

triggers a release point. In both cases, the return value is guessed and the reaction event that marks this fetching is appended to the local trace. The reaction event is built by obtaining relevant information from the trace through getTgt and getMtd functions. Becauseawait introduces a release point, we have to check the class invariantI holds before the actor can perform other tasks. The class invariant

I checks that the class attributes and the local trace satisfy the condition that must hold at release points. After which, the trace may be extended and the class attributes may change values as the actor works on other tasks. The actor then executes the rest of the method body, assuming that the class invariants hold. Ensuring that the well-formedness property holds is crucial to ensure that the result of fetching the resolved value of a future multiple times remains consistent. We assume for the verification purpose that a

SEQ

process is not suspended infinitely long, implying that every method call made by this process is always resolved. This assumption allows the reasoning part to cover as many parts of the implementation as possible.

As an example, we present the encoding of the Server class in

SEQ

(List- ing11.1), where the original statements which are changed in the encoding are

wlp(skip, Q) def= Q

wlp(abort, Q) def= true wlp(v := e,Q) def= Qve wlp(s1; s2, Q) def = wlp(s1, wlp(s2, Q)) wlp(ifb{ s1 }else{ s2 }, Q) def = (b ∧ wlp(s1, Q)) ∨ (¬b ∧ wlp(s2, Q)) wlp(m(x) body,Q) def= wlp(body,Q)

wlp(T y,Q) def= ∀y : Q wlp(x :=some, Q) def= ∀x : Q

wlp(assume b, Q) def= b =⇒ Q

wlp(assert b, Q) def= b ∧ Q

Figure 11.3.: Weakest liberal preconditions semantics for

SEQ

put as comments followed directly by their encoding. The encoding introduces to the class the generated events as they are generated. The statements that assign expressions to variables remain the same in the encoding. In the encoding, several logical variables are typically introduced to represent the values of generated by the non-deterministic assignments (e.g., t0andv0). The return statement is trans-

formed into an assignment to the default variablereturn. These logical variables

are helpful in constructing the encoding compositionally.