Previous: Function Definitions, Up: Programs [Contents][Index]
A TR-program definition has the form
Head
{
TR Rule
...
TR Rule
}
where Head is an atom or simple compound term and each TR Rule has one of the forms given below.
The most simple TR rule has the form
Guard
~>
TR Action
where Guard is a conjunct of goals and TR Action is of the form given below.
At the other extreme, the two most complete forms of a TR rule are
Guard
while
Whilemin_time
Duration~>
TR Action
and
Guard
inhibit
Inhibitmin_time
Duration~>
TR Action
where While and Inhibit are conjuncts of goals and Duration is a number.
The most simple rule above is a particular form of either of the most complete rule forms where
While and Inhibit are false
and both durations are
0
.
Other variations of the general form are:
Guard
min_time
Duration~>
TR Action
which is the same as
Guard
inhibit false min_time
Duration~>
TR Action
Semantically, when a TR program is executed, the guards are checked in order until a guard is found that is true (with a given instantiation of variables). The corresponding TR Action is then executed.
As with actions, if there are no matching guards, an exception is thrown.
In the case where the rule contains a while condition, while Guard (with the same instantiation of variables) is true or While is true or the duration of the while part hasn’t expired (since the time this rule was chosen) then this rule will continue to be the chosen unless an earlier guard becomes true.
In the case where the rule contains an inhibit condition, while Guard (with the same instantiation of variables) is true or Inhibit is true or the duration of the inhibit part hasn’t expired (since the time this rule was chosen) then this rule will continue to be the chosen unless an earlier guard becomes true and Inhibit becomes false.
At that point, the guards will be checked again from the beginning. If no earlier rule guards are true, the same rule will refire if the guard is true with a different instantiation of variables (and execute the corresponding actions using the new instantiation of variables) or will continue as long as the guard remains true with the same instantiation of variables or While is true or the while duration hasn’t expired or Inhibit is true or the inhibit duration hasn’t expired.
Note that executing TR Action will typically mean stopping durative actions from previous rule firings and starting new actions (both discreet and durative). As an optimization, instead of stopping a durative action with given arguments and starting the same action with different arguments, the system will generate a ’modify action’.
The forms of TR Action for each TR rule are given below.
A TR Action can be a call on a TR program (possibly a recursive call on the same program). When such a rule is fired this TR program is executed.
A TR Action can be a comma separated set of discreet and
durative robotic actions to be executed in parallel. ()
is the ’do nothing’ action.
A TR Action can be a semi-colon separated sequence of the form
[
Action:
Duration,
...,
Action:
Duration]
.
where the last action need not have a maximum duration.
Each action above can be either a call on a TR program or a set of discreet and durative robotic actions.
When called, the first action is called and then after that duration is up, the second action is called and so on until the last action in the sequence is called. After its duration has expired then the sequence is repeated from the start. This repetitive action continues whilst the rule with the timed sequence remains a fired rule. If the last duration is missing, that action persists whilst the rule with the timed sequence remains a fired rule. The sequence is execututed just once.
TR Actions can have Qulog actions attached as below.
TRAction
++
Action
When called, both TRAction and Action will be executed. The Qulog action is typically a modification to the belief store or a message send action.
As an example of TR Programs, consider the following TR program (from the examples/introduction
directory of the release) controlling a robot whose objective is to find, approach, and pick up an object using grippers.
%% We assume that if the program receives a dead_centre percept %% it will also receive a centre percept def dir::= left | right | centre | dead_centre percept see(num, dir), holding() def durative ::= move(num) | turn(dir) def discrete ::= grab() | release() %% We interpret holding true and see(0, centre) not true to mean that %% the grippers are closed but not actually holding an object tel get_object() get_object() { holding() & see(0, dead_centre) ~> () holding() & see(0, centre) ~> () not holding() & see(0, dead_centre) ~> grab() not holding() & see(0, centre) ~> grab() not holding() ~> get_to() true ~> release() } tel get_to() get_to() { see(0, dead_centre) ~> () see(0, centre) ~> () see(0, Dir) ~> turn(Dir) see(_, dead_centre) ~> move(6) see(_, centre) ~> move(6) see(_, Dir) inhibit not see(_, dead_centre) ~> move(4) , turn(Dir) true ~> [turn(left):10, move(4):10] }
Consider an initial state where no objects are seen and holding is false.
When get_object
is executed then the forth rule is fired causing
get_to
to be executed. The last of rules of get_to
will
be chosen (a timed interval). This will first cause the robot to start turning
for 10 seconds and then start moving for 10 seconds. This will be repeated until
an object is spotted.
At some point, say see(10, left)
becomes true. This causes the
sixth rule of get_to
to fire (with Dir
instantiated to
10
). Assuming this object is not moved by the environment, then
eventually, say see(8, centre)
becomes true. It might seem
that the fifth rule should now fire because its guard becomes true. However,
the inhibit condition prevents higher rules from firing. Once, say,
see(8, dead_centre)
becomes true then rule four will fire.
By over-achieving the guard of the sixth rule the "fluttering" between
the fifth and sixth rule (without the inhibit condition) is eliminated.
The while condition is necessary because it takes over from the guard and mantains rule six as the active rule when seeing to the left is no longer true but seeing to the centre becomes true.
On the other hand, if, before see(8, dead_centre)
becomes true
the environment moves the object so that see(8, right)
becomes
true then there would be a refiring of rule six and the robot will start
turning to the right.
Note that, if before the object is seen dead centre,
see(0, centre)
becomes true then rule four of get_object
will fire. The inhibit only has a local effect - affecting rule choices within its own TR program.
Eventually, without interference from the environment, either
see(0, dead_centre)
or see(0, centre)
will become true. The third or fourth rule of get_object
will now fire (stopping the execution of get_to
), causing the
robot to grip the object. Under normal circumstances holding will become
true and then the first or second rule will fire causing the robot to stop.
It may seem that the robot’s job is done now that it has achieved its goal. However, the TR program is still monitoring the state and say the environment now removes the object from the robot’s grip. Rule six will fire, opening the grippers, and then, once holding is no longer true, rule five will fire and the robot will go back to searching for an object.
Previous: Function Definitions, Up: Programs [Contents][Index]