Skip to content

🚧 Under Construction 🚧
The HTML version of the manual is currently under construction and slightly out of date. If you find it difficult to read, there is a PDF version available here.

The Soar Architecture

This chapter describes the Soar architecture. It covers all aspects of Soar except for the specific syntax of Soar’s memories and descriptions of the Soar user-interface commands.

This chapter gives an abstract description of Soar. It starts by giving an overview of Soar and then goes into more detail for each of Soar’s main memories (working memory, production memory, and preference memory) and processes (the decision procedure, learning, and input and output).

An Overview of Soar

The design of Soar is based on the hypothesis that all deliberate goal-oriented behavior can be cast as the selection and application of operators to a state. A state is a representation of the current problem-solving situation; an operator transforms a state (makes changes to the representation); and a goal is a desired outcome of the problem-solving activity.

As Soar runs, it is continually trying to apply the current operator and select the next operator (a state can have only one operator at a time), until the goal has been achieved. The selection and application of operators is illustrated in Figure 2.1.

Soar is continually trying to select and apply operators.

Soar has separate memories (and different representations) for descriptions of its current situation and its long-term procedural knowledge. In Soar, the current situation, including data from sensors, results of intermediate inferences, active goals, and active operators is held in working memory. Working memory is organized as objects. Objects are described in terms of their attributes; the values of the attributes may correspond to sub-objects, so the description of the state can have a hierarchical organization. (This need not be a strict hierarchy; for example, there’s nothing to prevent two objects from being "substructure" of each other.)

Long-term procedural knowledge is held in production memory. Procedural knowledge specifies how to respond to different situations in working memory, can be thought of as the program for Soar. The Soar architecture cannot solve any problems without the addition of long-term procedural knowledge. (Note the distinction between the "Soar architecture" and the "Soar program": The former refers to the system described in this manual, common to all users, and the latter refers to knowledge added to the architecture.)

A Soar program contains the knowledge to be used for solving a specific task (or set of tasks), including information about how to select and apply operators to transform the states of the problem, and a means of recognizing that the goal has been achieved.

Types of Procedural Knowledge in Soar

Soar’s procedural knowledge can be categorized into four distinct types of knowledge:

  1. Inference Rules
    In Soar, we call these state elaborations. This knowledge provides monotonic inferences that can be made about the state in a given situation. The knowledge created by such rules are not persistent and exist only as long as the conditions of the rules are met.
  2. Operator Proposal Knowledge
    Knowledge about when a particular operator is appropriate for a situation. Note that multiple operators may be appropriate in a given context. So, Soar also needs knowledge to determine which of the candidates to choose:
  3. Operator Selection Knowledge
    Knowledge about the desirability of an operator in a particular situation. Such knowledge can be either in terms of a single operator (e.g. never choose this operator in this situation) or relational (e.g. prefer this operator over another in this situation).
  4. Operator Application Rules
    Knowledge of how a specific selected operator modifies the state. This knowledge creates persistent changes to the state that remain even after the rule no longer matches or the operator is no longer selected.

Note that state elaborations can indirectly affect operator selection and application by creating knowledge that the proposal and application rules match on.

Problem-Solving Functions in Soar

These problem-solving functions are the primitives for generating behavior that is relevant to the current situation: elaborating the state, proposing candidate operators, comparing the candidates, and applying the operator by modifying the state. These functions are driven by the knowledge encoded in a Soar program.

Soar represents that knowledge as production rules. Production rules are similar to "if- then" statements in conventional programming languages. (For example, a production might say something like "if there are two blocks on the table, then suggest an operator to move one block on top of the other block"). The "if" part of the production is called its conditions and the "then" part of the production is called its actions. When the conditions are met in the current situation as defined by working memory, the production is matched and it will fire, which means that its actions are executed, making changes to working memory.

Selecting the current operator, involves making a decision once sufficient knowledge has been retrieved. This is performed by Soar’s decision procedure, which is a fixed procedure that interprets preferences that have been created by the knowledge retrieval functions. The knowledge-retrieval and decision-making functions combine to form Soar’s decision cycle.

When the knowledge to perform the problem-solving functions is not directly available in productions, Soar is unable to make progress and reaches an impasse. There are three types of possible impasses in Soar:

  1. An operator cannot be selected because no new operators are proposed.
  2. An operator cannot be selected because multiple operators are proposed and the comparisons are insufficient to determine which one should be selected.
  3. An operator has been selected, but there is insufficient knowledge to apply it.

In response to an impasse, the Soar architecture creates a substate in which operators can be selected and applied to generate or deliberately retrieve the knowledge that was not directly available; the goal in the substate is to resolve the impasse. For example, in a substate, a Soar program may do a lookahead search to compare candidate operators if comparison knowledge is not directly available. Impasses and substates are described in more detail in Impasses and Substates.

An Example Task: The Blocks-World

We will use a task called the blocks-world as an example throughout this manual. In the blocks-world task, the initial state has three blocks named A, B, and C on a table; the operators move one block at a time to another location (on top of another block or onto the table); and the goal is to build a tower withAon top,Bin the middle, andCon the bottom. The initial state and the goal are illustrated in Figure 2.2.

The Soar code for this task is available online at https://web.eecs.umich.edu/~soar/blocksworld.soar or in the here. You do not need to look at the code at this point.

A B C Initial State A B C Goal
The initial state and goal of the "blocks-world" task.

The operators in this task move a single block from its current location to a new location; each operator is represented with the following information:

  • the name of the block being moved
  • the current location of the block (the "thing" it is on top of)
  • the destination of the block (the "thing" it will be on top of)

The goal in this task is to stack the blocks so that C is on the table, with block B on top of block C, and block A on top of block B.

Representation of States, Operators, and Goals

The initial state in our blocks-world task - before any operators have been proposed or selected - is illustrated in Figure 2.3.

A state can have only one selected operator at a time but it may also have a number of potential operators that are in consideration. These proposed operators should not be confused with the active, selected operator.

Figure 2.4 illustrates working memory after the first operator has been selected. There are six operators proposed, and only one of these is actually selected.

Goals are either represented explicitly as substructures of the working memory state with general rules that recognize when the goal is achieved, or are implicitly represented in the Soar program by goal-specific rules that test the state for specific features and recognize when the goal is achieved. The point is that sometimes a description of the goal will be available in the state for focusing the problem solving, whereas other times it may not. Although representing a goal explicitly has many advantages, some goals are difficult to explicitly represent on the state.

For example, the goal in our blocks-world task is represented implicitly in the provided Soar program. This is because a single production rule monitors the state for completion of the goal and halts Soar when the goal is achieved. (Syntax of Soar programs will be explained in Chapter 3.) If the goal was an explicit working memory structure, a rule could compare the configuration of blocks to that structure instead of having the goal embedded within the rule’s programming.

An abstract illustration of the initial state of the blocks world as working memory objects. At this stage of problem solving, no operators have been proposed or selected.
An abstract illustration of working memory in the blocks world after the first operator has been selected.

Proposing candidate operators

As a first step in selecting an operator, one or more candidate operators are proposed. Operators are proposed by rules that test features of the current state. When the blocks- world task is run, the Soar program will propose six distinct (but similar) operators for the initial state as illustrated in Figure 2.5. These operators correspond to the six different actions that are possible given the initial state.

Comparing candidate operators: Preferences

The second step Soar takes in selecting an operator is to evaluate or compare the candidate operators. In Soar, this is done via rules that test the proposed operators and the current state, and then create preferences(stored in preference memory). Preferences assert the relative or absolute merits of the candidate operators. For example, a preference may say that operator A is a "better" choice than operator B at this particular time, or a preference may say that operator A is the "best" thing to do at this particular time. Preferences are discussed in detail in how preferences are evaluated to decide an operator.

The six operators proposed for the initial state of the blocks world each move one block to a new location.

Selecting a single operator: Decision

Soar attempts to select a single operator as a decision, based on the preferences available for the candidate operators. There are four different situations that may arise:

  1. The available preferences unambiguously prefer a single operator.
  2. The available preferences suggest multiple operators, and prefer a subset that can be selected from randomly.
  3. The available preferences suggest multiple operators,but neither case 1 or 2 above hold.
  4. The available preferences do not suggest any operators.

In the first case, the preferred operator is selected. In the second case, one of the subset is selected randomly. In the third and fourth cases, Soar has reached an impasse in problem solving, and a new substate is created. Impasses are discussed in Impasses and Substates.

In our blocks-world example, the second case holds, and Soar can select one of the operators randomly

Applying the operator

An operator applies by making changes to the state; the specific changes that are appropriate depend on the operator and the current state.

There are two primary approaches to modifying the state: indirect and direct. Indirect changes are used in Soar programs that interact with an external environment: The Soar program sends motor commands to the external environment and monitors the external environment for changes. The changes are reflected in an updated state description, garnered from sensors. Soar may also make direct changes to the state; these correspond to Soar doing problem solving "in its head". Soar programs that do not interact with an external environment can make only direct changes to the state.

Internal and external problem solving should not be viewed as mutually exclusive activities in Soar. Soar programs that interact with an external environment will generally have operators that make direct and indirect changes to the state: The motor command is represented as substructure of the state and it is a command to the environment. Also, a Soar program may maintain an internal model of how it expects an external operator will modify the world; if so, the operator must update the internal model (which is substructure of the state).

When Soar is doing internal problem solving, it must know how to modify the state descriptions appropriately when an operator is being applied. If it is solving the problem in an external environment, it must know what possible motor commands it can issue in order to affect its environment.

The example blocks-world task described here does not interact with an external environment. Therefore, the Soar program directly makes changes to the state when operators are applied. There are four changes that may need to be made when a block is moved in our task:

  1. The block that is being moved is no longer where it was (it is no longer "on top" of the same thing).
  2. The block that is being moved is in a new location (it is "on top" of a new thing).
  3. The place that the block used to be in is now clear.
  4. The place that the block is moving to is no longer clear — unless it is the table, which is always considered "clear".1

The blocks-world task could also be implemented using an external simulator. In this case, the Soar program does not update all the "on top" and "clear" relations; the updated state description comes from the simulator.

Making inferences about the state

Making monotonic inferences about the state is the other role that Soar long-term procedural knowledge may fulfill. Such elaboration knowledge can simplify the encoding of operators because entailments of a set of core features of a state do not have to be explicitly included in application of the operator. In Soar, these inferences will be automatically retracted when the situation changes such that the inference no longer holds.

For instance, our example blocks-world task uses an elaboration to keep track of whether or not a block is "clear". The elaboration tests for the absence of a block that is "on top" of a particular block; if there is no such "on top", the block is "clear". When an operator application creates a new "on top", the corresponding elaboration retracts, and the block is no longer "clear".

Problem Spaces

If we were to construct a Soar system that worked on a large number of different types of problems, we would need to include large numbers of operators in our Soar program. For a specific problem and a particular stage in problem solving, only a subset of all possible operators are actually relevant. For example, if our goal is to count the blocks on the table, operators having to do with moving blocks are probably not important, although they may still be "legal". The operators that are relevant to current problem-solving activity define the space of possible states that might be considered in solving a problem, that is, they define the problem space.

Soar programs are implicitly organized in terms of problem spaces because the conditions for proposing operators will restrict an operator to be considered only when it is relevant. The complete problem space for the blocks world is shown in Figure 2.6. Typically, when