Skip to content

gp

Generate productions according to a specified pattern.

Synopsis

gp { production_body }

Description

The gp command defines a pattern used to generate and source a set of Soar productions. production_body is a single argument that looks almost identical to a standard Soar rule that would be used with the sp command. Indeed, any syntax that is allowed in sp is also allowed in gp.

Patterns in gp are specified with sets of whitespace-seprated values in square brackets. Every combination of values across all square-bracketed value lists will be generated. Values with whitespaces can be used if wrapped in pipes. Characters can also be escaped with a backslash (so string literals with embedded pipes and spaces outside of string literals are both possible).

gp is primarily intended as an alternative to :template rules for reinforcement learning. :template rules generate new rules as patterns occur at run time. Unfortunately, this incurs a high run time cost. If all possible values are known in advance, then the rules can be generated using gp at source time, thus allowing code to run faster. gp is not appropriate when all possible values are not known or if the total number of possible rules is very large (and the system is likely to encounter only a small subset at run time). It is also possible to combine gp and :template (e.g., if some of the values are known and not others). This should reduce the run time cost of :template.

There is nothing that actually restricts gp to being used for RL, although for non-RL rules, a disjunction list (using << and >>) is better where it can be used. More esoteric uses may include multiple bracketed value lists inside a disjunction list, or even variables in bracketed value lists.

Each rule generated by gp has *integer appended to its name (where integer is some incrementing number).

Examples

Template version of rule:

sp {water-jug*fill
   :template
   (state <s1> ^name water-jug ^operator <op> +
               ^jug <j1> <j2>)
   (<op> ^name fill ^fill-jug.volume <fvol>)
   (<j1> ^volume 3 ^contents <c1>)
   (<j2> ^volume 5 ^contents <c2>)
-->
   (<s1> ^operator <op> = 0)
}

gp version of rule (generates 144 rules):

1
2
3
4
5
6
7
8
9
gp {water-jug*fill
   (state <s1> ^name water-jug ^operator <op> +
               ^jug <j1> <j2>)
   (<op> ^name fill ^fill-jug.volume [3 5])
   (<j1> ^volume 3 ^contents [0 1 2 3])
   (<j2> ^volume 5 ^contents [0 1 2 3 4 5])
-->
   (<s1> ^operator <op> = 0)
}

Esoteric example (generates 24 rules):

1
2
3
4
5
gp {strange-example
   (state <s1> ^<< [att1 att2] [att3 att4] >> [ val |another val| |strange val\|| ])
-->
   (<s1> ^foo [bar <bar>])
}

testgp.soar contains many more examples.

See Also