Soar fires its rules in parallel, such that all those which can fire will do so. However, the actions of such rules do not directly make changes to working memory; they produce votes for changes in the form of preferences. For example, one value can be better than another, and a third can be best. Note that elements can have more than one preference associated with them.
Soar's preferences fall into five categories:
Example usage:
;; Propose eat.
sp {ht*propose-op*eat
(state <s> ^problem-space.name hungry-thirsty)
(<s> ^hungry yes)
-->
(<s> ^operator <o>)
(<o> ^name eat +)}
Example usage:
sp {perform*initialise*state
(state <s> ^name perform)
-->
(<s> ^task <t>)
(<t> ^feature <f1> + <f1> &, <f2> + <f2> &)
(<f1> ^fname effect ^fvalue launch)
(<f2> ^fname arg1)}
Example usage:
;; Eat is better if you are hungry.
sp {ht*compare*eat*better*drink
(state <s> ^desired <d> ^problem-space.name hungry-thirsty)
(<d> ^hungry no)
(<s> ^operator <op-eat> +)
(<op-eat> ^name eat)
(<s> ^operator <op-drink> +)
(<op-drink> ^name drink)
-->
(<s> ^operator <op-eat> > <op-drink>)}
Example usage:
Typically these are not used in simple programs, and work with them
suggests that it is unwise to use them in many cases.
Example usage:
;; The reconsider preference effectively terminates the operator on
;; the next decision cycle after it has done what its supposed to do.
sp {ht*terminate*eat
(state <s> ^operator <o>)
(<o> ^name eat)
(<s> ^hungry no)
-->
(<s> ^operator <o> @)}
The semantics of the decision procedure are reasonably intuitive, at least in simple cases. For example, a single best wins. Should the candidates all be indifferent, then the indifferent-selection parameters can be used to define how selection takes place.