Go backward to Refractory inhibition of chunks.
Go up to Learning in Soar.
Problems with chunking
======================
One weaknesses of Soar is that chunking can create overgeneral productions
that apply in inappropriate situations, or overspecific productions that will
never fire. These problems arise when chunking cannot accurately summarize
the processing that led to the creation of a result. Below is a list of four
known problems in chunking.
1. Local negated conditions Overgeneral chunks can be created when negated
conditions test for the absence of a working memory element that, if it
existed, would be local to the subgoal. Chunking does not determine why
a given working memory element does not exist, and thus a condition that
occurred in a production in the subgoal is not included in the chunk.
For example, if a production tests for the absence of a local flag, and
that flag is copied down to the subgoal from a supercontext, then the
chunk should include a test that the flag in the supercontext does not
exist. Unfortunately, it is computationally expensive to determine why
a given working memory element does not exist. Chunking only includes
negated tests if they test for the absence of super-context working
memory elements. To avoid using negated conditions for local data, the
local data can be made a result by attaching it to the super-context.
This increases the number of chunks learned, but a negated condition for
the super-context can be used that leads to correct chunks.
2. Search control determines correctness
Overgeneral chunks can be
created if a result of problem solving in a subgoal is dependent on
search-control knowledge. Recall that desirability preferences, such as
better than, best, and worst, are not included in the traces of problem
solving used in chunking (Section *Note Determining conditions and
actions:: on page See Determining conditions and actions). In
theory, these preferences do not affect the validity of search. In
practice, however, a problem space can be implemented so that search
control *does* affect the correctness of search. Here are two examples:
1. Some of the test for correctness of a result is included in
productions that prefer operators that will produce correct
results. The system will work correctly only when those
productions are loaded.
2. An operator is given a worst preference, indicating that it should
be used only when all other options have been exhausted. Because
of the semantics of worst, this operator will be selected after all
other operators; however, if this operator then produces a result
that is dependent on the operator occurring after all others, this
fact will not be captured in the conditions of the chunk.
In both of these cases, part of the test for producing a result is
{implicit} in search control productions. This move allows the explicit
goal test to be simpler because any state to which the test is applied
is guaranteed to satisfy some of the requirements for success. However,
chunks created in such a problem space will be overgeneral because the
implicit parts of the goal test do not appear as conditions. To avoid
this problem, necessity preferences (require and prohibit) should be
used whenever a control decision is being made that also incorporates
goal-attainment knowledge. The necessity preferences are included in
the backtrace by chunking, thereby avoiding overgenerality.
3. Test for subgoal
Overgeneral chunks can be created if a result
of a subgoal is dependent on the creation of an impasse within the
subgoal. For example, processing in a subgoal may consist of
exhaustively applying all the operators in the problem space. If so,
then a convenient way to recognize that all operators have applied and
processing is complete is to wait for a state no-change impasse to
occur. When the impasse occurs, a production can test for the resulting
subgoal and create a result for the original subgoal. This form of goal
test builds overgeneral chunks because no pre-existing structure is
relevant to the result that terminates the subgoal. The result is
dependent only on the existence of the subgoal within a subgoal.
The current solution to this problem is to allow the problem solving to
signal the architecture that the test for a subgoal is being made. The
signal used by Soar is a test for the ^$quiescence t augmentation of the
subgoal. The chunking mechanism recognizes this test and does not build
a chunk when it is found in a backtrace of a subgoal. The history of
this test is maintained, so that if the result of the subgoal is then
used to produce further results for a super-context, no higher chunks
will be built. However, if the result is used as search control (it is
a desirability preference), then it does not prevent the creation of
chunks because the original result is not included in the backtrace. If
the ^$quiescence t being tested is connected to a supergoal, it will not
inhibit chunking and it will be included in the conditions of the chunk.
4. Testing changing values over time
Overspecific chunks can be
created if the results of a subgoal are dependent on multiple values of
a single super-context augmentation. Consider a simple example of where
the ticks of a clock are counted in the subgoal and the result of the
subgoal is to create "bong" when sixty ticks have gone by. The ticks
are created by removing and recreating a tick object in the top context,
while in the subgoal a count of the ticks is maintained. The final
result is dependent on sixty different ticks, which each occurred at a
different time. The chunk that is built will test for sixty ticks, all
occurring at once. The problem is that the relationship between the
sixty ticks is not represented explicitly, but is instead implicit in
the rematching of the production that increments the tick counter. This
particular problem could be solved by explicitly representing the after
relationship of a tick to the one that occurred before it, creating a
linked list of ticks. The subgoal can then test that a new tick has
occurred after the last one it counted, and bump its
count. Unfortunately, this requires explicitly representing all sixty
ticks at the top level and the resulting chunk will test for a linked
list of sixty ticks. Another solution is to make the intermediate count
a result of the subgoal and save only the two most recent ticks in
working memory. The intermediate count could have a pointer to the tick
used to increment it. Then, sixty chunks will be learned, one for each
addition.