Go backward to Proposal of the initial state.
Go up to Encoding A Task in Soar.
Go forward to Operator comparison.
Operator proposal
=================
In our implementation of the Blocks World, there is a single general
operator, which moves a block from one location to another. For a given
state, instantiations of this operator are created for moving each clear
block to either another clear block or the table. To create the operator
instantiations requires only one production, shown below. Each operator
instantiation has three attributes: ^name for the name of the operator, which
is always move-block; ^moving-block for the block being moved; and
^destination for the place (either a block or the table) the block is moving
to. At the same time that an operator is created, an acceptable preference is
created for it so that the operator can be selected.
(sp blocks-world*propose*operator*move-block
(goal <g> ^problem-space.name blocks-world ^state <s>)
(<s> ^object-dynamic <blockA-dyn>
{<> <blockA-dyn> <destination-dyn>})
(<blockA-dyn> ^object-static <blocka> ^clear yes -^ontop <destination>)
(<blocka> ^type block)
(<destination-dyn> ^object-static <destination> ^clear yes)
-->
(<g> ^operator <o> +)
(<o> ^name move-block ^moving-block <blocka> ^destination <destination>))
The conditions of this production test that an operator will be created only
if it can apply (<blocka> and <destination> must both be clear). After
testing for the name of the problem space, it tests that there is a block
that is clear, and another object, which can be either a block or a table,
that is clear. It also tests that those two places are not the same {<>
<blockA-dyn>}, so that it never attempts to move a block on top of itself.
Finally it tests that there does not exist an ontop relation with the block
to be moved (<block>) already on top of the place it is being moved to
(<destination>). Although this may seem redundent with testing that the
destination is clear, the table is always clear and this ensures that the
block will not be moved to the table if it is already on the table.
An alternative approach would be to have two productions, one that proposes
operators for moving a block onto a second block, and a second production
that proposes moving a block onto the table. If this approach were used,
there would be no need to represent that the table is clear because that
knowledge would be implicit in the production that proposed the operators.
The operator instantiations are created only if they can be applied, and are
automatically retracted when they no longer apply, so that no additional
productions are required to reject inapplicable operators. One alternative
would be to generate operator instantiations for moving every block onto
every other block (possibly including itself) and add productions that reject
operators when they are not applicable. A second alternative would be to use
means-ends analysis propose operators that will help achieve the goal.