• Keine Ergebnisse gefunden

3.2 Axiomatization of System Domains

3.2.4 Effect Axioms and Derived Fluent Functions

is to add axioms that describe how the values of fluents come about.

value, a variable that is introduced in the fluent or action template, or a fresh variable that is set in the clause body. In order to do this, the clause bodyΓ can use the last argument S of the effect axiom, which is a variable that will be set to the current situation during progression. Finally,Γ can be any valid Prolog goal that evaluates to true if and only if the effect should be applied and that binds all named variables in the effect axiom exceptS.

Some concrete examples for effect axioms of varying complexity can be found in Figure 3.5, which shows the effect axioms for the fluents defined in Figure 3.3. The first four specify that the robot’s horizontal velocityvx is set directly to either a leftward (−1) or rightward (1) movement by the horizontal move actions and set to0when the movement step finishes or fails or the robot starts a vertical move. Here, the new value is simply specified in the axiom itself and no calculation is needed. The axioms for the vertical velocityvyare not shown here because they are very similar to those of vx. In contrast to that, the effect axioms for the position fluent xpos are a bit more complex.

Here, for the effect of a successful step, i.e. astep_succeeded event, a clause body is specified that not only considers the direct effect on the position of the robot but also the indirect effect on the position of any item that is carried by the robot.

The axioms that follow after the movement effects establish some self-explanatory rules for when an item is carried by a robot. After that, the content of thenext_task fluent is defined. In this example, a single fluent is used to store both the assigned item and the assigned target workstation. To do that, a Prolog term is created with the arbitrary functord. Alternatively, it would also be possible to use two separate fluents to store the assignment. This choice is up to the modeler. In order to make sure that robots can be assigned new tasks after they have delivered an item, the netx_task fluent has to be reset tonone, which is specified by the second effect axiom fornext_task. Ad-ditionally, the reset also happens when the item is dropped, which indicates that the robots will later be equipped by a relenting control strategy that simply abandons a dropped item and waits for the next assignment (see Sec-tion 3.3). On the other hand, when an item is eventually delivered to its target workstation, the following effect axioms establish that this is tracked both by the fluentdelivered_tofor the item itself and bydelivered_item_countfor the workstation. At the other side of the delivery process, the effect axioms forrequest_queue handle the contents of the request queue. When a request message from a workstation arrives, the workstation’s id is added to the list that is stored inrequest_queueusing Prolog’s built-inappendfunction. Con-sistent to that, this entry is removed again when it has been processed, i.e.

when an item has been a assigned to be delivered to the requesting station.

Finally, in the last effect axiom, it is stated that a collision of a severity level higher than7 will break both robots.

effect(vx(Robot), move_right(Robot), _, 1, _).

effect(vx(Robot), move_left(Robot), _, -1, _).

effect(vx(Robot), move_up(Robot), _, 0, _).

effect(vx(Robot), move_down(Robot), _, 0, _).

effect(vx(Robot), step_succeeded(Robot), _, 0, _).

effect(vx(Robot), step_failed(Robot), _, 0, _).

. . . similar for vy

effect(xpos(O), step_succeeded(Robot), _, X, S) :-(O = Robot, ! ; carrying(Robot, O, S)),

vx(Robot, Vx, S), xpos(Robot, OldX, S), X is OldX + Vx.

. . . similar for ypos

effect(carrying(Rob, Item), grab(Rob, Item, _), _, true, _).

effect(carrying(Rob, Item), drop(Rob, Item), _, false, _).

effect(carrying(Rob, Item), deliver(Rob, Item, _), _, false, _).

effect(carrying(Rob, Item), accidental_drop(Rob, Item), _, false, _).

effect(next_task(Rob), assign_task(_, Rob, Item, Workstation), _, d(Item, Workstation), _).

effect(next_task(Rob), deliver(Rob, _, _), _, none, _).

effect(next_task(Rob), drop(Rob, _), _, none, _).

effect(next_task(Rob), accidental_drop(Rob, _), _, none, _).

effect(delivered_to(Item), deliver(_, Item, Station), _, Station, _).

effect(delivered_item_count(Ws), deliver(_, _, Ws), OldCount, NewCount, _) :-NewCount is OldCount + 1.

effect(request_queue(C), request(Ws, C), OldQueue, NewQueue, _) :-append(OldQueue, [Ws], NewQueue).

effect(request_queue(C), assign_task(C, _, _, Ws), OldQueue, NewQueue, _) :-delete(Ws, OldQueue, NewQueue), !.

effect(broken(Rob), collision(R1, R2, Severity), _, true, _) :-(R1 = Rob, ! ; R2 = Rob), Severity > 7.

Figure 3.5: Effect axioms in the multi-robotics example.

As mentioned before, the SALMA runtime automatically translates effect axioms into successor state axioms in the form that was introduced in Sec-tion 2.2. In fact, during the model initializaSec-tion phase, a new dynamicfluent clause is added to the Prolog clause database which combines all effect ax-ioms for the fluent and adds a default case that returns the original value for any action term that is not covered by the effect axioms. The clause for a fluentf with parametersx1, . . . , xnwill have the form f(x1, . . . , xn, S):-Γ. for a boolean (i.e. relational) fluent and f(x1, . . . , xn, V, S):-Γ. for a functional fluent, where S is the situation variable and V will be bound to the value of the fluent instance.

Besides regular fluents, whose contents are updated in each step according to the effect axioms, a model can also containderived fluents whose values are calculated based on the values of others. Hence, derived fluents are just situa-tion dependent funcsitua-tions and predicates that are specified like normal Prolog predicates. In fact, for each derived fluent declarationderived fluent(f,[x1 : t1, . . . , xn:tn], tf)., the modeler has to add a Prolog clause with a signature of the formf(X1, . . . , Xn, V, S) or f(X1, . . . , Xn, S) whereX1, . . . Xn are Prolog variables that represent the derived fluents parameters,V a variable that will be bound to the return value, and S a variable that will contain the current situation when the derived fluent is evaluated. For a boolean (i.e. relational) derived fluent, the return value is not needed, so the second form is used. Both forms can be seen in Figure 3.6 that shows the derived fluents for the running example. Most of these definitions are quite self-explanatory. The clause for dist_from_stationcalculates the Manhattan distance (see [Bla06]) between a robot and a workstation, which is used because robots can only move in strictly horizontal or vertical steps. The predicate unassigned is simply a check that next_task contains none for a given robot, and moving checks whether the absolute value of a robot’s velocity is higher than0. Additionally, the predicate ready is used as a shortcut to check whether the robot is ready for the next step, which requires it to be functional and not moving. Another shortcut isundelivered, which will be used by the coordinator’s control proce-dure to select items that neither have already been delivered nor are currently scheduled to be delivered to a workstation. Finally, the two derived fluents task_itemandtask_workstationextract the item and the workstation from an assignment term. As will be shown in Section 3.3, this is helpful for the definition of control procedures because it avoids having to deal with Prolog terms within Python.