Add Another KS

The last exercise made it easy to initialize and run our application
repeatedly by simply starting the Agenda Shell. We also specified the
dimensionality of our known-world space instance relative to the
dimensional specifications of the location unit class. With
these niceties in place, its time to move beyond our initial
location unit instance.

This exercise shows you how to:

Add an additional dimension to a unit class

Define a KS that obtains its execution-context information from its
triggering unit instance

It's time we introduce the notion of time to our application. Edit the
location unit-class definition in
tutorial-example.lisp, adding a new slot, time, to the
location unit class definition and a corresponding time
dimensional value:

Checks if we've already walked for 75 locations and prints a message if
we have.

Otherwise:

Determines a random location for which the x and y values are within 10
of the x and y values of the triggering unit instance (that is, the
location instance whose creation triggered the
random-walk-ks KS)

If both of the x and y values for the new random location are between
-50 and 50, creates a location unit instance at the random
location; otherwise, prints a message indicating that we've walked off the
world

Because add-linear-variance is stochastic, your results will be
similar but not identical. Note that we used GBBopen's printv
macro to display the result of each generated value. Printv can
greatly assist debugging by printing forms and the results of evaluating
them. Printv can be transparently wrapped around any form in a
complex function definition, as it evaluates and displays all the forms in
its body and returns the values resulting from evaluating the last form:

Unlike the KS-execution functions that we have defined previously,
random-walk-ks-function does not ignore its ksa argument.
Instead, it calls sole-trigger-instance-of with the ksa
unit-instance argument in order to obtain the location unit
instance whose creation triggered the KSA. This pattern of obtaining the unit
instance that triggered a KSA and then using that triggering unit instance as
the context for the KS execution is typical of many KSs.

It looks like something happened! (Again, because
add-linear-variance is stochastic, your results will be similar
but not identical.) Let's look at the blackboard repository and see how many
location unit instances were created:

The 61 location instances makes sense. Previously, it required
3 control-shell cycles to create the initial location unit
instance (one to execute the initial-ks KSA followed by two
additional cycles of quiescence before the Agenda Shell exits). We now create
one additional location unit instance with every execution of
random-walk-ks, so we always create 3 fewer
location instances than the total number of control-shell
cycles.

This is a bad idea for several reasons. First, we are looking up every
location unit instance by its instance name, which is less
efficient than operating on location instances directly. While
this isn't an significant issue in expressions that we evaluate in the REPL to
investigate our application, we should seek to avoid such inefficiencies in
application code. More importantly, however, the location
instance name just happens to mirror the sequencing that we really want to
display: the time value of the locations. We should find a way to
sequence location printing that relies on the time values
directly.

GBBopen provides a variant of map-instances-of-class, called
map-sorted-instances-of-class, that sorts the unit instances
based on a comparison predicate and an optional :key accessor function
that suits our needs:

Usingmap-sorted-instances-of-class involves a sorting
operation, so this approach still has some efficiency concerns for use in
application code. However, it suits our REPL-exploration needs just fine.
(There is a do-sorted-instances-of-class macro, if an
iterative style is preferred over a mapper.) We will explore a more efficient
approach to displaying the random walk in the next exercise.