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 most complete form of a TR rule is
Guard while
While min
Duration until
Until min
Duration
~>
TR Action
where While and Until are conjuncts of goals and Duration is a number.
The most simple rule above is a particular form of the full rule where both
While and Until are false
and both durations are
0
.
Other variations of the general form are:
Guard min
Duration ~>
TR Action
which is the same as
Guard while false min
Duration until false min
Duration ~>
TR Action
and
Guard while_until
Goal min
Duration ~>
TR Action
which is the same as
Guard while not Goal min
Duration until Goal min
Duration ~>
TR Action
and
Guard while_until
Goal ~>
TR Action
which is the same as
Guard while not
Goal min 0 until
Goal min 0 ~>
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.
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 rule until Until becomes true and the until duration has expired.
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. Otherwise, the guards of the rules below this rule are checked.
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 sequence of discreet and
durative actions. The special sequence ()
is the ’do nothing’ action.
A TR Action can be a comma separated sequence of the form
Action for
Duration ,
... ,
Action for
Duration.
where the last duration can be elided.
Each action above can be either a call on a TR program or a sequence of discreet or durative 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 will repeat until a different rule is fired. If the last duration is missing, it as treated as infinity.
A TR Action can be of the form
Action Sequence wait
Duration ^
Repeats
When called, the actions will be executed, and after Duration seconds the actions will be executed again. This will be repeated Repeats times unless another rule is chosen. If another rule is not chosen then an error will be generated.
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 dir::= left | right | centre | dead_centre percept see : (num, dir), holding : () durative move : (num), turn : (dir) 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 get_object : () ~> get_object { holding & see(0, centre) ~> () not holding & see(0, centre) ~> grab wait 10^2 not holding ~> get_to true ~> release wait 10^2 } get_to : () ~> get_to { see(0, centre) ~> () see(0, Dir) ~> turn(Dir) see(_, centre) ~> move(6) see(_, Dir) while see(_, centre) until see(_, dead_centre) ~> move(4) , turn(Dir) true ~> turn(left) for 10 ; move(4) for 10 }
Consider an initial state where no objects are seen and holding is false.
When get_object
is executed then the third 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
fourth 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 third rule should now fire because its guard becomes true. However,
the until condition prevents higher rules from firing. Once, say,
see(8, dead_centre)
becomes true then rule three will fire.
By over-achieving the guard of the third rule the "fluttering" between
the third and fourth rule (without the until condition) is eliminated.
The while condition is necessary because it takes over from the guard and mantains rule four 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 four 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 two of get_object
will fire. The until only has a local effect - affecting rule choices within its own TR program.
Eventually, without interference from the environment,
see(0, centre)
will become true. The second 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 rule will fire causing the robot to stop.
If, however, there was a mechnical problem with the gripper, the robot will wait for 10 seconds and try to close the gripper again in the hope that the problem will disappear. If the problem doesn’t clear up after two attemps (with a 10 second wait for each) then an error will be produced.
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 four will fire, opening the grippers, and then, once holding is no longer true, rule three will fire and the robot will go back to searching for an object.
Previous: Function Definitions, Up: Programs [Contents][Index]