w3c / cogai

for work by the Cognitive AI community group
Other
54 stars 25 forks source link

Avoiding loops #11

Open draggett opened 4 years ago

draggett commented 4 years ago

Looping is a problem for badly designed rule sets. For machine generated rules, the system can compare how long a rule set takes compared to what is expected, and to forcefully abandon execution if it is taking too long. This can be combined with reinforcement learning to evolve effective rule sets.

In principle, a reasoning system can help to propose good rules that follow proven design patterns. This can involve some concept of recipes that constrain random choices. Reinforcement learning should be applicable to such recipes!

Rules need to be written to avoid the same rule being repeatedly fired without any progress. In the counting demo, the goal is updated to drive progress on the succeeding digit. The rule's conditions ensure that the rule isn't reapplied after processing the last digit.

By contrast, some other demos invoke external actions that push new goals to the goal queue, and the current goal needs to be cleared to prevent the current rule looping, and to make way for acting on the new goals in the queue. Ideally, you wouldn't need to explicitly clear the current goal, but it is proving hard to figure out how to do that implicitly.

The robot demo requires clearing the goal buffer which will then pop the queue if there is a pending goal. For the start rule, the actions initiate waits that in some cases are immediately satisfied, resulting in pushing goals to the goal queue.

If there is @do clear at start of the actions, the start goal is cleared. A subsequent call to pushBuffer then triggers the rule engine. If @do clear is at the end of the actions, it will result in a call to popBuffer which likewise will trigger the rule engine.

How could we make the @do clear implicit?

Looping on the same goal doesn't make any sense for this demo as there are no changes to it, and the same rule would re-apply. In other words, if at the end of this rule, its conditions are still all true, we need to make a change.

If the rule only involves a single buffer, it is clear that we should clear that buffer, but if multiple buffers are involved, what should we do? This involves deducing which buffer needs to be cleared/popped, how? What are some cases of interest?

Changing a property is usually a means to prepare for the next execution of this rule, e.g. as in the counting demo. However, not all such changes will be correct and an indefinite loop may still be possible. Another scenario is where one buffer stays the same but another changes, so that the same rule no longer applies.

I suspect the only way to be sure is to re-evaluate the rule's conditions. However, that isn't sufficient, as we still don't know what to do. Doing nothing will keep the old goal in the buffer despite there being new goals in the queue. The only idea I have right now is to introduce a syntax to clear the buffer for a given condition. However, that isn't a real advantage over the explicit @do clear.