/*!

\page essay07  Enablement

<hr>

Enablement

\section Introduction Introduction

There is an additional problem I am still mulling over.

\li  This has to do with "mode" timelines.  A mode timeline does not have "return
status" and "return status flag" parameters. This is a problem when one
tries to establish enablement.  What I am seeing right now in the Gromit
model is that the end of a mode token is set to "now" as soon as the first
of a series of tests that polls the hardware goes through, even if the
result is not successful. 

\li  I think that the issue is that as soon as the
first test succeeds, the end of the "mode token" is temporally enabled. I
suspect that the current assumption is that if temporally enabled a mode
token is always enabled. But this is incorrect since planning has not
occurred yet and the decision to test again (test token contained by the
mode token) has not been taken yet.  Note that the other decision, to
postpone indefinitely the end of the token, does not work either because if
the test succeeds, then the token should be terminated.

\li  What we are facing is the fact that a mode token that propagate the results
of a computation (either performed externally (return and values of an
executable token) or internally (propagation from other previously
unconstrained parameters) should clearly identify when these results are
indeed available (status flag True), not available (flag unset) or we have
given up on receiving them (pre-emption, indicated by status flag False).

\li The rule for enablement that I described applies to internal tokens
as well.

\li  The problem with mode tokens is identifying the direction of communication
*between timelines* rather than *among agents*.  This actually fits the model
of distributed constraint propagation and updates that should really be at
the foundation of IDEA.  A model should work just the same whether it is
split across multiple agents or inside a single agent. The only thing that
changes is the visibility of timelines and the latency of an agent operating
on a piece of the database. The latter requires the possible communication
of plans (larger pieces of the network) rather than single tokens (as we do
now). 

\li  Fixing this completely would require a massive change, because we would have
to either declare or identify propagation of execution status across a plan.
Note that this would have to work both for parts of the plan that are
restricted by the new values (i.e., a new value restricts an unbound value
to a singleton) and also confirmation of values due to propagation. This should
apply only to status flags and status values. So, if an executable token
receives a status and its flag is set to TRUE, we would have to track which
return statuses are affected by this arrival. 

\li  This would mean that tracking
in parallel a single variable per token (i.e., whether the return status has
actually been received or set to false) we actually need to duplicate at
least partially the constraint network that connects the return status
values. This because the return status of a token could be deduced from the
*actually received* return status value in dependency with the return value
itself.

\li  This is an extension of the concept we discovered a while ago (several years
ago, for that matter) of the difference between a plan's prediction (it is
allowed to predict success in a plan with no uncertainty) versus what
actually happens (the confirmation of the value from an external message or
the actual carrying out of a computation).

\li  I suspect people have already encountered things like this (especially
Vijay). If you have suggestion on how to solve my problem, please advise.


\li  A goal token with no (or undecided) status which can end now (and has a
direct successor which is enabled) is currently ended now. 

\li  Nicola makes a suggestion that we do NOT end a goal token which can end now
and has a direct successor and is enabled if it has an undecided
status-flag.

Nicola continues:

\li  To be more precise the rule to implement is the following:

   During the "time fixing" pre-processing preceding the actual reactive
planning search, for every ENABLED event, fix the time according the
following heuristic:
     IF the event is the start of a token, fix the time to the current time
     IF the event is not the start of a token, do not fix the time

\li  The crucial definition is the one of an "ENABLED EVENT". 

    An event is "enabled" if:
        a) all its predecessors have executed (i.e., their time bound is a
singleton less or equal to the current time);
        b) its earliest time is greater or equal to the current time;
        c) the IDEA agent has been given explicit authority to set the time.

\li  A "predecessor" is an event such that there is a link (direct or implied) in
the temporal network that connects it to the original event with lower bound
greater or equal to zero. Another way to say this (using the formulation of
the temporal network as a distance graph) is that there is a distance link
(direct or implied) from an event to its predecessor such that its weight is
non-positive.

\li  Condition (c) above is THE CRUCIAL missing concept in the current plan
runner/reactive planner.

\li  Authority to set the time is explicitly given by setting the return status
flag of the token (or the tokens) that is (are) ended by the event. In the
past, we have seen the status flag as a "marker" that determines, after the
fact, whether a return value/status is valid after a token has ended, i.e.,
if it has been communicated from/to a separate agent. Setting the *STATUS
FLAG* (and only the status flag) in the plan, however, is also used by the
plan runner as an assertion of who has authority to execute the end event of
a token.

\li  The "authority" associated to the end of a token is complemented between
"executable" and "goal" tokens, as follows:

Goal token:

Who has authority                Status flag

   IDEA agent                         True
   Nature                                False

Executable token:

Who has authority                Status/Value flag

   IDEA agent                         False
   Nature                                True

\li  Note that in IDEA the end of a token with a return status flag has always
shared authority if the token can be pre-empted. If there is no return
status, the execution authority is always with the IDEA agent (Nature) if
the token is executable (goal).

\li  If the status flag can only be set to True, the token cannot be pre-empted.
In this case the authority is always with Nature (the IDEA agent) if the
token is executable (goal). The latter restriction could be imposed in the
model by constraining the values of the status flag in the topmost
compatibility definition (one that has no other argument restricted).

\li  So what happens if the authority has not been explicitly set? According to
the above definition of enablement, the event will *not* be enabled. This is
the case no matter whether the event ends an executable or a goal.

\li  Note that it is *not* incorrect for the reactive planner to enable an event
that was "undecided" at the beginning of the execution cycle. This is true
if the planner can produce a consistent plan.

\li  Unfortunately in our case the search *is not* unified. It separates a first
phase when temporal decisions are made *without search or awareness of open
subgoals* and a subsequent search phase that *does not know how to make
temporal commitments decisions directly*. We have always been plagued by
this and have put off resolving this for fear of its consequences...

\li  The problem is that we *first* fix the time of events that we want to terminate
and *then* we search to build a consistent plan.

\li  Suppose that (as it is occurring in LITA) the arrival of a status message
terminates the currently executable token (in LITA it is the token that
commands the navigator to go to a waypoint that is interrupted by a "no-arc"
fault). Suppose that the currently executable token is "contained_by" (but
does not have a constraint on end-time equality) with a goal token (in
LITA's case, the high-level goal to move to a waypoint included in the LITA
plan).

\li   If we used the current faulty (and subconscious)  notion of
authority, the termination of the executable token could propagate "temporal
enablement" to the goal according to conditions a) and b) of the definition
of enablement. This is due to the existence of a 0-distance connecting the
end of the goal to the end of the executable (coming from the end-link of
the contained_by relation).  But additional compatibilities may need to be
activated to recover and these could introduce new "contained_by"
constraints with the goal token which would invalidate the temporal part of
the enablement condition. So, until planning is done, we should *not* decide
that the goal token should be terminated.

\li  Note that strictly speaking is not *incorrect* to terminate the goal token
if this is done in the context of a reactive planning search that ties
together considerations about fixing times and open compatibilities.

\li  However, it is *incorrect* in our specific search because the time decision
is made *out of context*, not knowing what the subsequent search will
actually face.

\li  So, the fix is implementing in full the definition of temporal enablement I
gave above, in all parts of the reactive planner/plan runner.

\li  I don't believe there is any additional branch. If (as you should  ) you
move the "enablement propagation" at the end, what you need to do is
propagate not from an "uncontrollable" event but from a "not-enabled"
event.

\li  The test of whether a token is not-enabled is the same as the one you are
supposed to use to fix gnats 2598 already, i.e., an event is not enabled if
one of the following case occur: a) the event ends an executable token with
return status flag set to True; b) the event ends a goal token with return
status flag set to False; or c) the return status flag of the ended token is
not set.

\li  All I am suggesting is that we clearly separate the test for "controllability" from
the test for "enablement".


[Follow-on Message]

\li  The basic issue was that, lacking the explicit information on "propagated
enablement" in the Drive_TurnTo_Absolute token (it being a mode token), the
decision on whether to terminate it or not was done entirely based on the
presence or not of a successor token.

\li  While Drive_TurnTo_Absolute did not have a successor in the plan I was
executing, a token controlling the low-level mobility capabilities,
Rflex_MoveAtSpeed, was constrained to end at the same time as
Drive_TurnTo_Absolute *and* had a successor. This was due to the fact that
the Rflex token did not have any parameters. This meant that it was assumed
it could be pre-empted from Drive_TurnTo_Absolute.

\li  Of course, given correct enablement semantics, there could not be a
termination decision made by the IDEA agent on Rflex_MoveAtSpeed because the
only way to terminate it would have to be by propagation. But, given our
incorrect semantics, the token was terminated asap because it had a
successor and this terminated the Drive_TurnTo_Absolute.

\li  The solution is to add a dummy successor selector in Rflex_MoveAtSpeed. The
deliberative planner would be prevented from making a decision on the variable,
leaving open the successor of Rflex_MoveAtSpeed. This in turn causes the end
time of Rflex_MoveAtSpeed not to be set. The time will be set when
Drive_TurnTo_Absolute actually terminates. At this point the successor
selector will become active for reactive planning and, through a choice that
should be forced to a single value (I use a True Boolean value) for the
successor selector, the successor of Rflex_MoveAtSpeed is selected.

\li  This solution will work in all cases in which deliberative planning does not
involve mode tokens whose end times are predecessors of end token events
whose enablement condition is not set (like in the case of the
Drive_TurnTo_Absolute). We could run in this situation if we had a plan
communicated from outside but the actual start time of successive tokens
would still have to be communicated by a controlling agent.

\li  Needless to say, I believe that at present this does not occur in our
domains since if a plan has been communicated it is assumed that the agent
will be free to determine when the start time of the goals can occur without
further communication from the external controlling agent (think of a LITA
plan made of external goals but such that the goals are communicated in
batch mode by TEMPEST).

\li  This is going to bite us when we will try to communicate plans and update
directives on how to execute a plan at run time.

\li  But for now we should be fine.

<hr>

\li  I don't know if David made the change. I assume he did not (I think he is
waiting for me to write up what is supposed to happen). If he did make the
change, I suppose there is a bug. The status_flag is not set. So both for an
executable token and for a goal token the event should be considered as
"non-resolved" (i.e., neither "nature" or "the executive" has taken
responsibility for terminating it) and therefore it should be postponed (it
is treated the same as an uncontrollable end).

\li  I'll write up the explanation of what needs to happen shortly.

\li  Im having some issues with the enablement criterion for uncontrollable 
tokens following controllable ones.  The PlanManager has begun setting more 
realistic start and end time ranges to reflect reasonable bounds on event 
durations, particularly minimum values.  Unfortunately, these are being treated 
as strict minimums by the Executive.  For example, if a champstack  time 
ranges are specified as follows:
 
<StartRange min=45 max=inf/>
<EndRange min=185 max=inf/>
 
\li  and if my model specifies a minimum duration of 1, then the Executive will wait 
until time 184 to start the champzstack.   In general, Im a little worried about 
specifying minimum durations on events, since there are always exceptions, and I 
dont want to fail because were going too fast!  If possible, I think it would be 
best for now to specify minimums to be 1 second.  
 
\li  As for maximum values, the Exec is currently only reading your StartRange and 
EndRange values.  Since they almost always end with infinity, it cannot yet 
pick up on token maximum durations.  Ill have to start reading your DurationRange 
values if we want to restrict execution based on timing


*/
