From d03103e584ed90732c3fe61c08e2d1a080f752dd Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Tue, 8 Sep 2026 21:49:38 +0200 Subject: [PATCH 1/7] chore: upgrade to Zensical modern theme from mkdocs material --- .github/workflows/check_pr.yml | 3 +- .github/workflows/publish.yml | 37 ++ .github/workflows/publish_mkdocs.yml | 28 -- README.md | 15 +- .../sublimetext_soar_tools_package/index.md | 12 + docs/home/tags.md | 2 +- docs/soar_manual/02_TheSoarArchitecture.md | 64 +++- docs/soar_manual/03_SyntaxOfSoarPrograms.md | 13 +- .../04_ProceduralKnowledgeLearning.md | 40 ++- docs/soar_manual/05_ReinforcementLearning.md | 3 + docs/soar_manual/06_SemanticMemory.md | 3 + docs/soar_manual/07_EpisodicMemory.md | 3 + docs/soar_manual/08_SpatialVisualSystem.md | 24 +- docs/soar_manual/09_SoarUserInterface.md | 274 +++++++------- docs/support/index.md | 11 +- docs/tutorials/IntroSoarDebugger/index.md | 39 ++ docs/tutorials/soar_tutorial/01.md | 6 + docs/tutorials/soar_tutorial/07.md | 3 + docs/tutorials/soar_tutorial/08.md | 9 + docs/workshops/19.md | 3 + docs/workshops/20/index.md | 3 + docs/workshops/23.md | 3 + docs/workshops/24/index.md | 3 + docs/workshops/25/index.md | 3 + docs/workshops/26/index.md | 3 + docs/workshops/27.md | 3 + docs/workshops/28.md | 3 + docs/workshops/29.md | 3 + docs/workshops/31.md | 3 + docs/workshops/32.md | 3 + docs/workshops/33.md | 6 + docs/workshops/34.md | 6 + docs/workshops/35.md | 3 + docs/workshops/36.md | 3 + docs/workshops/37.md | 6 + docs/workshops/41.md | 3 + docs/workshops/45.md | 6 + hooks.py | 52 --- main.py | 10 +- mkdocs.yml | 337 +++++++++--------- overrides/partials/copyright.html | 27 +- requirements.txt | 6 +- 42 files changed, 633 insertions(+), 454 deletions(-) create mode 100644 .github/workflows/publish.yml delete mode 100644 .github/workflows/publish_mkdocs.yml delete mode 100644 hooks.py diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml index 78efbe8f..19943f9e 100644 --- a/.github/workflows/check_pr.yml +++ b/.github/workflows/check_pr.yml @@ -32,5 +32,4 @@ jobs: config: '.markdownlint.json' - run: pip install -r requirements.txt - - run: mkdocs build -s -v - + - run: zensical build --clean diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 00000000..f763d07d --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,37 @@ +name: Publish site + +on: + push: + branches: + - main + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +# Allow one concurrent deployment, don't cancel in-progress runs +concurrency: + group: pages + cancel-in-progress: false + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/configure-pages@v5 + - uses: actions/setup-python@v5 + with: + python-version: 3.x + - run: pip install -r requirements.txt + - run: zensical build --clean + - uses: actions/upload-pages-artifact@v3 + with: + path: site + - uses: actions/deploy-pages@v4 + id: deployment diff --git a/.github/workflows/publish_mkdocs.yml b/.github/workflows/publish_mkdocs.yml deleted file mode 100644 index 73088457..00000000 --- a/.github/workflows/publish_mkdocs.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Publish mkdocs - -on: - push: - branches: - - main - workflow_dispatch: - -permissions: - contents: write - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 - with: - python-version: 3.x - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v3 - with: - key: mkdocs-material-${{ env.cache_id }} - path: .cache - restore-keys: | - mkdocs-material- - - run: pip install -r requirements.txt - - run: mkdocs gh-deploy --force diff --git a/README.md b/README.md index 0899b7dc..ee13a239 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,10 @@ Soar cognitive architecture, including source for the PDF's distributed with Soa The website is not yet fully migrated from the old site, and is still under construction. -The site is built using the [MkDocs](https://www.mkdocs.org/), a static site -generator that uses Markdown files to generate a website. The theme is -[Material for MkDocs](https://squidfunk.github.io/mkdocs-material/). +The site is built with [Zensical](https://zensical.org/), a static site +generator from the Material for MkDocs team that uses Markdown files to +generate a website. It reads the existing `mkdocs.yml` config and renders +with the Material "classic" theme variant. Large files that are not displayed but rather downloaded should not be stored here; instead, put them in the [website downloads repository](https://github.com/SoarGroup/website-downloads) @@ -19,9 +20,9 @@ and link to them here. ```shell python -m venv venv -source venv/bin/activate (or venv\Scripts\activate on Windows) +source venv/bin/activate # (or venv\Scripts\activate on Windows) pip install -r requirements.txt -mkdocs serve # add -s to abort on any warnings +zensical serve # add -s to abort on any warnings; zensical build for a one-off build ``` ## Deployment @@ -30,6 +31,10 @@ The site is deployed to GitHub Pages automatically as long as the build workflow don't fail. Run it locally to ensure you haven't introduced an error, and then just push your commit to the `main` branch and the site will be updated automatically. +Deployment uses the GitHub Actions Pages pipeline (`.github/workflows/publish.yml`, +`zensical build` + `actions/deploy-pages`). The repository's *Settings → Pages → +Build and deployment → Source* must be set to **GitHub Actions**. + ## Updates for New Soar Versions * Update the `soar_version` variable in `mkdocs.yml`. diff --git a/docs/downloads/agent_development_tools/sublimetext_soar_tools_package/index.md b/docs/downloads/agent_development_tools/sublimetext_soar_tools_package/index.md index 49154678..3982ab90 100644 --- a/docs/downloads/agent_development_tools/sublimetext_soar_tools_package/index.md +++ b/docs/downloads/agent_development_tools/sublimetext_soar_tools_package/index.md @@ -40,16 +40,25 @@ The plugin highlights both Soar productions and other curly-braced sections, like `smem --add` commands: ![Syntax highlighting](./Images/sublime-soar-syntax-highlighting.jpeg) +/// caption +Syntax highlighting +/// #### Snippets Production snippets help you code faster: ![Production snippets](./Images/sublime-soar-prod-snippets.jpg) +/// caption +Production snippets +/// and SoarDoc snippets help you document faster: ![SoarDoc snippets](./Images/sublime-soar-soardoc-snippets.png) +/// caption +SoarDoc snippets +/// #### SoarUnit Build Command @@ -65,6 +74,9 @@ project [Readme](https://github.com/garfieldnate/Sublime-Soar-Tools) for setup details). Highlighting included! ![Soar REPL](./Images/sublime-soar-repl.jpeg) +/// caption +Soar REPL +/// ## Contributions Welcome diff --git a/docs/home/tags.md b/docs/home/tags.md index fef9bb4a..ab723897 100644 --- a/docs/home/tags.md +++ b/docs/home/tags.md @@ -2,4 +2,4 @@ Following is a list of relevant tags: -[TAGS] + diff --git a/docs/soar_manual/02_TheSoarArchitecture.md b/docs/soar_manual/02_TheSoarArchitecture.md index 6a7e6f15..c29b309b 100644 --- a/docs/soar_manual/02_TheSoarArchitecture.md +++ b/docs/soar_manual/02_TheSoarArchitecture.md @@ -20,6 +20,9 @@ operator (a state can have only one operator at a time), until the goal has been The selection and application of operators is illustrated in Figure 2.1. ![Soar is continually trying to select and apply operators.](Images/select-apply.svg) +/// caption +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 @@ -45,20 +48,20 @@ problem, and a means of recognizing that the goal has been achieved. Soar’s procedural knowledge can be categorized into four distinct types of knowledge: -1. *Inference Rules* +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* +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* +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* +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. @@ -117,6 +120,9 @@ and can be [viewed in the manual here](blocksworld.md#blocksworld-soar-rules). You do not need to look at the code at this point. ![The initial state and goal of the "blocks-world" task.](Images/blocks.svg) +/// caption +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: @@ -160,9 +166,15 @@ 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.](Images/ab-wmem.svg) +/// caption +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.](Images/ab-wmem2.svg) +/// caption +An abstract illustration of working memory in the blocks world after the first operator has been selected. +/// ### Proposing candidate operators @@ -186,6 +198,9 @@ 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.](Images/blocks-proposal.svg) +/// caption +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 @@ -277,6 +292,9 @@ for proposing operators will restrict an operator to be considered only when it The complete problem space for the blocks world is shown in Figure 2.6. Typically, when ![The problem space in the blocks-world includes all operators that move blocks from one location to another and all possible configurations of the three blocks.](Images/blocks-ps.svg) +/// caption +The problem space in the blocks-world includes all operators that move blocks from one location to another and all possible configurations of the three blocks. +/// Soar solves a problem in this problem space, it does not explicitly generate all of the states, examine them, and then create a path. Instead, Soar isin a specific state at a given time @@ -372,7 +390,7 @@ The elements in working memory arise from one of four sources: - (b) Operator augmentations: The decision procedure creates the operator augmentation of the state based on preferences. This records the selection of the current operator. -3. ***Memory Systems*** +3. ***Memory Systems*** 4. ***SVS*** 5. ***The Environment***: External I/O systems create working memory elements on the input-link for sensory data. @@ -414,6 +432,9 @@ conditions and a set of actions. If the conditions of a production match working memory, the production *fires*, and the actions are performed. ![An abstract view of production memory. The productions are not related to one another.](Images/ab-prodmem.svg) +/// caption +An abstract view of production memory. The productions are not related to one another. +/// ### The structure of a production @@ -471,7 +492,7 @@ to that state. ### Architectural roles of productions -Soar productions can fulfill the following four roles, by retrieving +Soar productions can fulfill the following four roles, by retrieving [different types of procedural knowledge](#types-of-procedural-knowledge-in-soar): 1. Operator proposal @@ -663,6 +684,9 @@ a particular type of impasse. The others occur when the number of candidates has reduced to one (necessarily the winner) or zero (a no-change impasse). ![An illustration of the preference resolution process. There are eight steps; only five of these provide exits from the resolution process.](Images/newprefsem.svg) +/// caption +An illustration of the preference resolution process. There are eight steps; only five of these provide exits from the resolution process. +/// Each step in Figure 2.8 is described below: @@ -699,7 +723,7 @@ ory. - **BetterWorseFilter (>), (<)** This filter removes any candidates that are worse than an- other candidate. -- **Exit point 2**: +- **Exit point 2**: - If the set of remaining candidates is empty, a conflict impasse is created returning the set of all candidates passed into this filter, i.e. all of the conflicted operators. - If the set of remaining candidates has one member, preference semantics terminates and this set is returned. @@ -776,6 +800,9 @@ set of matching productions, another cycle ensues. This repeats until the set of rules remains unchanged, a situation called **quiescence**. ![A detailed illustration of Soar’s decision cycle.](Images/decisioncycle.svg) +/// caption +A detailed illustration of Soar’s decision cycle. +/// After quiescence is reached in the *Proposal* phase, the *Decision* phase ensues, which is the architectural selection of a single operator, if possible. Once an operator is selected, the @@ -810,7 +837,7 @@ the external environment. Input is processed at the beginning of each execution cycle and output occurs at the end of each execution cycle. See [Soar I/O: Input and Output in Soar](./03_SyntaxOfSoarPrograms.md#soar-io-input-and-output-in-soar) for more information. -A simplified version of the Soar algorithm: +A simplified version of the Soar algorithm: ``` Soar while (HALT not true) Cycle; @@ -881,7 +908,7 @@ situation and the impasse cannot be resolved by additional preferences. #### No-change impasse A *no-change* impasse arises if a new operator is not selected during -the decision procedure. There are two types of no-change impasses: +the decision procedure. There are two types of no-change impasses: - A **State no-change impasse** occurs when there are no `acceptable` (or `require`) preferences to suggest operators for the current state (or all the `acceptable` @@ -898,8 +925,8 @@ failure impasse at the same time. In these cases, Soar detects only the constrai impasse. The impasse is detected *during* the selection of the operator, but happens -because one of the four problem-solving functions (described in -[Problem-Solving function in Soar](#problem-solving-functions-in-soar)) +because one of the four problem-solving functions (described in +[Problem-Solving function in Soar](#problem-solving-functions-in-soar)) was incomplete. ### Creating New States @@ -934,6 +961,9 @@ subgoals are considered to be added to the bottom of the stack; the first state called the *top-level state.*[3](#footnote3) See Figure 2.11 for a simplified illustrations of a subgoal stack. ![A simplified illustration of a subgoal stack.](Images/stack1.svg) +/// caption +A simplified illustration of a subgoal stack. +/// Soar continually attempts to retrieve knowledge relevant to all goals in the subgoal stack, although problem-solving activity will tend to focus on the most recently created state. @@ -1004,7 +1034,7 @@ supports any subgoal results. Soar determines i-support or o-support for the justification and its actions just as it would for any other production, as described in section -[Production Actions and Persistence](#production-actions-and-persistence). +[Production Actions and Persistence](#production-actions-and-persistence). If the justification is an operator application, the result will receive o-support. Otherwise, the result gets i-support from the justification. If such a result loses i-support from the justification, it will be retracted if there @@ -1088,7 +1118,7 @@ sp {elaborate*state*operator\*name ( ^name something)} ``` -the RHS action gets i-support. Of course, the state bound to `` is destroyed when +the RHS action gets i-support. Of course, the state bound to `` is destroyed when `( ^operator )` retracts, so o-support would make little difference. On the other hand, this production, @@ -1359,8 +1389,14 @@ Figure 2.13, at time $t_0$ , because only i-supported features have been created the dependency set is empty. ![Simplified Representation of the context dependencies (above the line), local o-supported WMEs (below the line), and the generation of a result. Prior to GDS, this situation led to non-contemporaneous constraints in the chunk that generates 3.](Images/simple-ncc.svg) +/// caption +Simplified Representation of the context dependencies (above the line), local o-supported WMEs (below the line), and the generation of a result. Prior to GDS, this situation led to non-contemporaneous constraints in the chunk that generates 3. +/// ![The Dependency Set in Soar.](Images/gomor-o-support.svg) +/// caption +The Dependency Set in Soar. +/// Three types of features can be tested in the creation of an o-supported feature. Each requires a slightly different type of update to the dependency set. @@ -1455,4 +1491,4 @@ computationally expensive than attempting to identify the specific dependent ass "goal." While these terms are often used nearly-interchangeably in the context of Soar, states refer to the set of WMEs comprising knowledge related to a peculiar level of goal. TheGoalDependency Set is the set of state elements upon - which a goal depends. + which a goal depends. diff --git a/docs/soar_manual/03_SyntaxOfSoarPrograms.md b/docs/soar_manual/03_SyntaxOfSoarPrograms.md index 6e626e83..4df55bf5 100644 --- a/docs/soar_manual/03_SyntaxOfSoarPrograms.md +++ b/docs/soar_manual/03_SyntaxOfSoarPrograms.md @@ -205,6 +205,9 @@ WMEs tested in the conditions. The link is one-way, from the identifier to the value. Less commonly, the attribute of a WME may be an identifier. ![A semantic net illustration of four objects in working memory.](Images/o43net.svg) +/// caption +A semantic net illustration of four objects in working memory. +/// This figure illustrates four objects in working memory; the object with identifier `X44` has been linked to the object with identifier `O43`, using the @@ -383,7 +386,7 @@ is printed using the [`print` command](../reference/cli/cmd_print.md). ### Production type (optional) A production may also include an optional _production type_, which may specify -that the production should be considered a default production (``:default`) or a +that the production should be considered a default production (`:default`) or a chunk (`:chunk`), or may specify that a production should be given o-support (`:o-support`) or i-support (`:i-support`). Users are discouraged from using these types. @@ -518,7 +521,7 @@ Syntactically, a variable is a symbol that begins with a left angle-bracket non-pipe (|) character in between. In the example production in Figure 3.2, there are seven variables: ``, -``, ``, `,,`, and ``. +``, ``, ``, ``, ``, and ``. The following table gives examples of legal and illegal variable names. @@ -2542,6 +2545,9 @@ runtime; this is just an example of possible bindings): ``` ![An example portion of the input link for the blocks-world task.](Images/blocks-inputlink.svg) +/// caption +An example portion of the input link for the blocks-world task. +/// The ’[A]’ notation in the example is used to indicate the working memory elements that are created by the architecture and not by the input function. @@ -2565,6 +2571,9 @@ creating a structure on the output link, such as: ``` ![An example portion of the output link for the blocks-world task.](Images/blocks-outputlink.svg) +/// caption +An example portion of the output link for the blocks-world task. +/// An output function would look for specific structure in this output link and translate this into the format required by the external program that controls diff --git a/docs/soar_manual/04_ProceduralKnowledgeLearning.md b/docs/soar_manual/04_ProceduralKnowledgeLearning.md index 747a4762..5ffc640c 100644 --- a/docs/soar_manual/04_ProceduralKnowledgeLearning.md +++ b/docs/soar_manual/04_ProceduralKnowledgeLearning.md @@ -152,6 +152,9 @@ To remedy this limitation and produce more general chunks, EBBS creates and analyzes a behavior trace. Figure below shows an example behavior trace. ![A close-up of a trace showing differences between a working memory trace (left) and a behavior trace (right). The working memory trace only contains the literal values of the WMEs that matched. The behavior trace, on the other hand, contains variables and various constraints on the values those variables can hold.](Images/chunking-wm-vs-exp-trace.png) +/// caption +A close-up of a trace showing differences between a working memory trace (left) and a behavior trace (right). The working memory trace only contains the literal values of the WMEs that matched. The behavior trace, on the other hand, contains variables and various constraints on the values those variables can hold. +/// Note that this trace is generated dynamically as rules match. Whenever a rule matches during agent execution, Soar creates an internal record of the rule that @@ -181,6 +184,9 @@ basis for the behavior trace used for a learning episode. (At this point, the behavior trace is a subgraph of the instantiation graph.) ![A visualization of the behavior trace of a chunk learned by the arithmetic agent. Each box represents a rule that fired in the substate. Arrows show dependencies between rules that create working memory elements and conditions that test those working memory elements.](Images/chunking-trace.png) +/// caption +A visualization of the behavior trace of a chunk learned by the arithmetic agent. Each box represents a rule that fired in the substate. Arrows show dependencies between rules that create working memory elements and conditions that test those working memory elements. +/// EBBS also creates an identity graph as it incrementally builds the instantiation @@ -239,6 +245,9 @@ same underlying object. Identities can be shared in the following situations.

![A behavior trace of two simple rules that matched in a substate.](Images/chunking-trace2.png) +/// caption +A behavior trace of two simple rules that matched in a substate. +/// To get a better picture of what a shared identity is, consider the two simple rules and the behavior trace of how they matched in a substate as shown in @@ -288,6 +297,9 @@ that share an identity in the figure are colored the same.

![A behavior trace incorporating identity analysis.](Images/chunking-trace-identity.png) +/// caption +A behavior trace incorporating identity analysis. +/// While it’s not readable in this figure, note that each identity is assigned a numeric ID. Both the explainer and the visualizer annotate elements of an @@ -300,6 +312,9 @@ on the identity graph. ![Note that the two rows on the bottom indicate when each component occurs during Soar’s processing.](Images/chunking-ebbs-components.png) +/// caption +Note that the two rows on the bottom indicate when each component occurs during Soar’s processing. +/// ### The Nine Components of Explanation-Based Behavior Summarization @@ -1408,11 +1423,11 @@ information about the chunk singleton command. **Printing Rules:** -- To print all chunks learned: +- To print all chunks learned: `print --chunks` or `print -c` -- To print all justifications learned (and still matching): +- To print all justifications learned (and still matching): `print --justifications` or `print -j` -- To print a rule or justification: +- To print a rule or justification: `print ` For more information on print, see the @@ -1420,16 +1435,16 @@ For more information on print, see the **Trace Messages:** -- To print when new rules are learned (just the name): +- To print when new rules are learned (just the name): `trace --learning 1` or `trace -l 1` -- To print when new rules are learned (the full rule): +- To print when new rules are learned (the full rule): `trace --learning 2` or `trace -l 2` - To print a trace of the conditions as they are collected during - backtracing: + backtracing: `trace --backtracing` or `trace -b` -- To print warnings about chunking issues detected while learning: +- To print warnings about chunking issues detected while learning: `trace --chunk-warnings` or `trace -C` -- To print when learned chunks match and fire: +- To print when learned chunks match and fire: `trace --backtracing` or `trace -b` For more information on trace, see the @@ -1501,11 +1516,11 @@ using the explain mechanism as described in the #### Interrupting Execution To Examine Learning -- To stop Soar after each successful learning episode: +- To stop Soar after each successful learning episode: `chunk interrupt on` -- To stop Soar after detecting any learning issue: +- To stop Soar after detecting any learning issue: `chunk warning-interrupt on` -- To stop Soar after learning a rule that the explainer recorded: +- To stop Soar after learning a rule that the explainer recorded: `chunk explain-interrupt on` For more information about how to record when a specific rule is learned, @@ -1835,6 +1850,9 @@ either Soar exits or a `soar init` is executed. This option is still considered experimental and in beta. ![A colored visualization of a behavior trace](Images/chunking-trace-identity.png) +/// caption +A colored visualization of a behavior trace +/// ## Visualizing the Explanation diff --git a/docs/soar_manual/05_ReinforcementLearning.md b/docs/soar_manual/05_ReinforcementLearning.md index 6a31f8de..3661252f 100644 --- a/docs/soar_manual/05_ReinforcementLearning.md +++ b/docs/soar_manual/05_ReinforcementLearning.md @@ -348,6 +348,9 @@ RL operator at the superstate remains selected is dependent upon the processing in the impasse state. Consider the operator trace in the following figure: ![Example Soar substate operator trace.](Images/rl-optrace.svg) +/// caption +Example Soar substate operator trace. +/// - At decision cycle 1, RL operator `O1` is selected in `S1` and causes an operator-no-change impasse for three decision cycles. diff --git a/docs/soar_manual/06_SemanticMemory.md b/docs/soar_manual/06_SemanticMemory.md index 4b44670a..301f73db 100644 --- a/docs/soar_manual/06_SemanticMemory.md +++ b/docs/soar_manual/06_SemanticMemory.md @@ -71,6 +71,9 @@ identifier `@1`, with four augmentations, representing the addition fact of $6 + 7 = 13$ (or, rather, 3, carry 1, in context of multi-column arithmetic). ![Example long-term identifier with four augmentations.](Images/smem-concept.svg) +/// caption +Example long-term identifier with four augmentations. +/// ### Integrating Long-Term Identifiers with Soar diff --git a/docs/soar_manual/07_EpisodicMemory.md b/docs/soar_manual/07_EpisodicMemory.md index a4bfba88..890d6bdf 100644 --- a/docs/soar_manual/07_EpisodicMemory.md +++ b/docs/soar_manual/07_EpisodicMemory.md @@ -418,6 +418,9 @@ average/total time for episode storage. Thus, the settings of page size for long, complicated runs establishes the ![Example episodic memory cache setting data.](Images/epmem-cache.png) +/// caption +Example episodic memory cache setting data. +/// desired balance of reactivity (i.e. max computation) and average speed. To ground this discussion, the above figure depicts maximum and average episodic diff --git a/docs/soar_manual/08_SpatialVisualSystem.md b/docs/soar_manual/08_SpatialVisualSystem.md index f9676066..c785226c 100644 --- a/docs/soar_manual/08_SpatialVisualSystem.md +++ b/docs/soar_manual/08_SpatialVisualSystem.md @@ -21,6 +21,9 @@ propagates the relationships implicit in spatial environments, and doesn't suffer from the frame problem that relational representations have. ![(a) Typical environment setup without using SVS. (b) Same environment using SVS.](Images/svs-setup.svg) +/// caption +(a) Typical environment setup without using SVS. (b) Same environment using SVS. +/// ## The scene graph @@ -42,6 +45,9 @@ respect to the chassis?). The scene graph always contains at least a root node: the **world node**. ![(a) A 3D scene. (b) The scene graph representation.](Images/scene_graph.svg) +/// caption +(a) A 3D scene. (b) The scene graph representation. +/// Each node other than the world node has a transform with respect to its parent. A transform consists of three components: @@ -712,10 +718,10 @@ bool node_test(sgnode* a, sgnode* b, const filter_params* p) For an example of how the following base filters are used, see filters/intersect.cpp. -- node_test_filter +- node_test_filter For each input pair (a, b) this outputs the boolean result of . -- node_test_select_filter - For each input pair (a, b) this outputs node b if . +- node_test_select_filter + For each input pair (a, b) this outputs node b if . (Can choose to select b if the test is false by calling ). #### Node Comparison Filters @@ -729,14 +735,14 @@ double node_comparison(sgnode* a, sgnode* b, const filter_params* p) For an example of how the following base filters are used, see filters/distance.cpp. -- node_comparison_filter +- node_comparison_filter For each input pair (a, b), outputs the numerical result of `node_comparison(a, b)`. -- node_comparison_select_filter +- node_comparison_select_filter For each input pair (a, b), outputs node b if `min <= node_comparison(a, b) <= max`. Min and max can be set through calling `set_min(double)` and `set_max(double)`, or as specified by the user through the filter_params. -- node_comparison_rank_filter +- node_comparison_rank_filter This outputs the input pair (a, b) for which `node_comparison(a, b)` produces the highest value. To instead have the lowest value output call `set_select_highest(true)`. @@ -752,13 +758,13 @@ double node_evaluation(sgnode* a, const filter_params* p) For an example of how the following base filters are used, see filters/volume.cpp. -- node_evaluation_filter +- node_evaluation_filter For each input node a, this outputs the numerical result of . -- node_evaluation_select_filter +- node_evaluation_select_filter or each input node a, this outputs the node if . Min and max can be set through calling and , or as specified by the user through the filter_params. -- node_evaluation_rank_filter +- node_evaluation_rank_filter This outputs the input node a for which produces the highest value. To instead have the lowest value output call . diff --git a/docs/soar_manual/09_SoarUserInterface.md b/docs/soar_manual/09_SoarUserInterface.md index 61f35e5b..a30405d5 100644 --- a/docs/soar_manual/09_SoarUserInterface.md +++ b/docs/soar_manual/09_SoarUserInterface.md @@ -69,88 +69,88 @@ settings for Soar. The specific commands described in this section are: -- [soar](../reference/cli/cmd_soar.md#soar) +- [soar](../reference/cli/cmd_soar.md#soar) Commands and settings related to running Soar. Use **soar ?** for a summary of sub-commands listed below. - - - soar init + + - soar init Reinitialize Soar so a program can be rerun from scratch. - - - soar stop + + - soar stop Interrupt a running Soar program. - - - soar max-chunks + + - soar max-chunks Limit the number of chunks created during a decision cycle. - - - soar max-dc-time + + - soar max-dc-time Set a wall-clock time limit such that the agent will be interrupted when a single decision cycle exceeds this limit. - - - soar max-elaborations + + - soar max-elaborations Limit the maximum number of elaboration cycles in a given phase. - - - soar max-goal-depth + + - soar max-goal-depth Limit the sub-state stack depth. - - - soar max-memory-usage + + - soar max-memory-usage Set the number of bytes that when exceeded by an agent, will trigger the memory usage exceeded event. - - - soar max-nil-output-cycles + + - soar max-nil-output-cycles Limit the maximum number of decision cycles executed without producing output. - - - soar max-gp + + - soar max-gp Set the upper-limit to the number of productions generated by the gp command. - - - soar stop-phase + + - soar stop-phase Controls the phase where agents stop when running by decision. - - - soar tcl + + - soar tcl Controls whether Soar Tcl mode is enabled. - - - soar timers + + - soar timers Toggle on or off the internal timers used to profile Soar. - - - soar version + + - soar version Returns version number of Soar kernel. - - - soar waitsnc + + - soar waitsnc Generate a wait state rather than a state-no-change impasse. -- [run](../reference/cli/cmd_run.md#run) +- [run](../reference/cli/cmd_run.md#run) Begin Soar’s execution cycle. -- exit +- exit Shut down the Soar environment. Terminates Soar and exits the kernel. `stop exit` -- [help](../reference/cli/cmd_help.md#help) +- [help](../reference/cli/cmd_help.md#help) Provide formatted, on-line information about Soar commands. - [decide](../reference/cli/cmd_decide.md#decide) Commands and settings related to the selection of operators during the Soar decision process - - - decide indifferent-selection + + - decide indifferent-selection Controls indifferent preference arbitration. - - - decide numeric-indifferent-mode + + - decide numeric-indifferent-mode Select method for combining numeric preferences. - - - decide predict + + - decide predict Predict the next selected operator - - - decide select + + - decide select Force the next selected operator - - - decide set-random-seed + + - decide set-random-seed Seed the random number generator. -- [alias](../reference/cli/cmd_alias.md#alias) +- [alias](../reference/cli/cmd_alias.md#alias) Define a new alias, or command, using existing commands and arguments. @@ -167,39 +167,39 @@ the contents and statistics of procedural memory. The specific commands described in this section are: -- [sp](../reference/cli/cmd_sp.md#sp) +- [sp](../reference/cli/cmd_sp.md#sp) Create a production and add it to production memory. -- [gp](../reference/cli/cmd_gp.md#gp) +- [gp](../reference/cli/cmd_gp.md#gp) Define a pattern used to generate and source a set of Soar productions. -- [production](../reference/cli/cmd_production.md#production) +- [production](../reference/cli/cmd_production.md#production) Commands to manipulate Soar rules and analyze their usage - - - production break + + - production break Set interrupt flag on specific productions. - - - production excise + + - production excise This command removes productions from Soar’s memory. - - - production find + + - production find Find productions that contain a given pattern. - - - production firing-counts + + - production firing-counts Print the number of times productions have fired. - - - production matches + + - production matches Print information about the match set and partial matches. - - - production memory-usage + + - production memory-usage Print memory usage for production matches. - - - production optimize-attribute + + - production optimize-attribute Declare an attribute as multi-attributes so as to increase Rete production matching efficiency. - - - production watch + + - production watch Trace firings and retractions of specific productions. **sp** is of course used in virtually all Soar programming. Of the remaining @@ -222,32 +222,32 @@ memory. The specific commands described in this section are: -- [print](../reference/cli/cmd_print.md#print) +- [print](../reference/cli/cmd_print.md#print) Print items in working, semantic and production memory. Can also print the print the WMEs in the goal dependency set for each goal. -- [wm](../reference/cli/cmd_wm.md#wm) +- [wm](../reference/cli/cmd_wm.md#wm) Commands and settings related to working memory and working memory activation. - - - wm activation + + - wm activation Get/Set working memory activation parameters. - - - wm add + + - wm add Manually add an element to working memory. - - - wm remove + + - wm remove Manually remove an element from working memory. - - - wm watch + + - wm watch Print information about wmes that match a certain pattern as they are added and removed. -- [preferences](../reference/cli/cmd_preferences.md#preferences) +- [preferences](../reference/cli/cmd_preferences.md#preferences) Examine items in preference memory. -- [svs](../reference/cli/cmd_svs.md#svs) +- [svs](../reference/cli/cmd_svs.md#svs) Perform spatial visual system commands. Of these commands, **print** is the most often used (and the most @@ -261,11 +261,11 @@ This section describes the commands for enabling and configuring Soar’s mechanisms of chunking and reinforcement learning. The specific commands described in this section are: -- [chunk](../reference/cli/cmd_chunk.md#chunk) +- [chunk](../reference/cli/cmd_chunk.md#chunk) Set the parameters for explanation-based chunking, Soar’s learning mechanism. -- [rl](../reference/cli/cmd_rl.md#rl) +- [rl](../reference/cli/cmd_rl.md#rl) Get/Set RL parameters and statistics. ## Long-term Declarative Memory @@ -274,10 +274,10 @@ This section describes the commands for enabling and configuring Soar’s long-term semantic memory and episodic memory systems. The specific commands described in this section are: -- [smem](../reference/cli/cmd_smem.md#smem) +- [smem](../reference/cli/cmd_smem.md#smem) Get/Set semantic memory parameters and statistics. -- [epmem](../reference/cli/cmd_epmem.md#epmem) +- [epmem](../reference/cli/cmd_epmem.md#epmem) Get/Set episodic memory parameters and statistics. ## Other Debugging Commands @@ -292,71 +292,71 @@ Soar’s performance. The specific commands described in this section are: -- [trace](../reference/cli/cmd_trace.md#trace) +- [trace](../reference/cli/cmd_trace.md#trace) Control the information printed as Soar runs. *(was watch)* -- [output](../reference/cli/cmd_output.md#output) +- [output](../reference/cli/cmd_output.md#output) Controls sub-commands and settings related to Soar’s output. - - - output enabled + + - output enabled Toggles printing at the lowest level. - - - output console + + - output console Redirects printing to the the terminal. Most users will not change this. - - - output callbacks + + - output callbacks Toggles standard Soar agent callback-based printing. - - - output log + + - output log Record all user-interface input and output to a file. - - - output command-to-file + + - output command-to-file Dump the printed output and results of a command to a file. - - - output print-depth + + - output print-depth Set how many generations of an identifier’s children that Soar will print - - - output warnings + + - output warnings Toggle whether or not warnings are printed. - - - output verbose + + - output verbose Control detailed information printed as Soar runs. - - - output echo-commands + + - output echo-commands Set whether or not commands are echoed to other connected debuggers. -- [explain](../reference/cli/cmd_explain.md#explain) +- [explain](../reference/cli/cmd_explain.md#explain) Provides interactive exploration of why a rule was learned. -- [visualize](../reference/cli/cmd_visualize.md#visualize) +- [visualize](../reference/cli/cmd_visualize.md#visualize) Creates graph visualizations of Soar’s memory systems or processing. -- [stats](../reference/cli/cmd_stats.md#stats) +- [stats](../reference/cli/cmd_stats.md#stats) Print information on Soar’s runtime statistics. -- [debug](../reference/cli/cmd_debug.md#debug) +- [debug](../reference/cli/cmd_debug.md#debug) Contains commands that provide access to Soar’s internals. Most users will not need to access these commands - - - debug allocate + + - debug allocate Allocate additional 32 kilobyte blocks of memory for a specified memory pool without running Soar. - - - debug port + + - debug port Returns the port the kernel instance is listening on. - - - debug time + + - debug time Uses a default system clock timer to record the wall time required while executing a command. - - - debug internal-symbols + + - debug internal-symbols Print information about the Soar symbol table. -Of these commands, **trace** is the most often used (and the most complex). +Of these commands, **trace** is the most often used (and the most complex). **output print-depth** is related to the **print** command. **stats** is useful *for understanding how much work Soar is doing. @@ -368,66 +368,66 @@ save/retrieve information to/from files, redirect the information printed by Soar as it runs, and save and load the binary representation of productions. The specific commands described in this section are: -- [cd](../reference/cli/cmd_file_system.md#cd) +- [cd](../reference/cli/cmd_file_system.md#cd) Change directory. -- [dirs](../reference/cli/cmd_file_system.md#dirs) +- [dirs](../reference/cli/cmd_file_system.md#dirs) List the directory stack. -- [load](../reference/cli/cmd_load.md#load) +- [load](../reference/cli/cmd_load.md#load) Loads soar files, rete networks, saved percept streams and external libraries. - - - load file + + - load file Sources a file containing soar commands and productions. May also contain Tcl code if Tcl mode is enabled. - - - load library + + - load library Loads an external library that extends functionality of Soar. - - - load rete-network + + - load rete-network Loads a rete network that represents rules loaded in production memory. - - - load library + + - load library Loads soar files, rete networks, saved percept streams and external libraries. -- ls +- ls List the contents of the current working directory. -- popd +- popd Pop the current working directory off the stack and change to the next directory on the stack. -- pushd +- pushd Push a directory onto the directory stack, changing to it. -- pwd +- pwd Print the current working directory. -- [save](../reference/cli/cmd_save.md#save) +- [save](../reference/cli/cmd_save.md#save) Saves chunks, rete networks and percept streams. - - - save agent + + - save agent Saves the agent’s procedural and semantic memories and settings to a single file. - - - save chunks + + - save chunks Saves chunks into a file. - - - save percepts + + - save percepts Saves future input link structures into a file. - - - save rete-network + + - save rete-network Saves the current rete networks that represents rules loaded in production memory. -- [echo](../reference/cli/cmd_echo.md#echo) +- [echo](../reference/cli/cmd_echo.md#echo) Prints a string to the current output device. -(See also the [output command](../reference/cli/cmd_output.md#ouput).) +(See also the [output command](../reference/cli/cmd_output.md#output).) The **load file** command, previously known as **source**, is used for nearly every Soar program. The directory functions are important to understand so that users diff --git a/docs/support/index.md b/docs/support/index.md index 6d1da268..16efff5e 100644 --- a/docs/support/index.md +++ b/docs/support/index.md @@ -26,9 +26,16 @@ To join a list, sign up on the mailing list page, and then simply send an e-mail * [**soar-help**](https://groups.google.com/d/forum/soar-help) is for users to ask questions. If you are experienced with Soar, please consider joining and participating in the discussions. * [**soar-cognitive-architecture**](https://groups.google.com/d/forum/soar-cognitive-architecture) is used for announcements and higher level discussions. We recommend that all people who are interested in Soar join the soar-cognitive-architecture mailing list to keep up to date with the latest developments in the Soar community. -Note: All mailing lists have a web archive of previous messages, so you can look for answers to previous questions. +!!! note + + All mailing lists have a web archive of previous messages, so you can look + for answers to previous questions. ## GitHub Issues You can report bugs and request features using Soar's Github repository's [issue tracker](https://github.com/SoarGroup/Soar/issues). -Note: If you have a question, please do not post an issue for it and use the soar-help mailing list instead. + +!!! note + + If you have a question, please do not post an issue for it and use the + soar-help mailing list instead. diff --git a/docs/tutorials/IntroSoarDebugger/index.md b/docs/tutorials/IntroSoarDebugger/index.md index a8e1b9eb..79490e9b 100644 --- a/docs/tutorials/IntroSoarDebugger/index.md +++ b/docs/tutorials/IntroSoarDebugger/index.md @@ -28,6 +28,9 @@ working with the language. On launch you should see a display similar to this: ![Screenshot of default debugger display](./Images/1.png) +/// caption +Screenshot of default debugger display +/// The window on the left side is the main trace window. As Soar executes, debug information is streamed to this window. @@ -41,6 +44,9 @@ into the line to the left of the Expand button. You should be rewarded with a display like this: ![Screenshot showing output of run 20](./Images/2.png) +/// caption +Screenshot showing output of run 20 +/// This is hard to read but the trace window on the left shows the series of operators that have just fired during the course of the first 20 decisions. You should also @@ -62,11 +68,17 @@ the command prompt. This should result in a display like this: ![Screenshot showing output of run 20 with watch level set to 5](./Images/3.png) +/// caption +Screenshot showing output of run 20 with watch level set to 5 +/// The trace looks similar, but doing the obvious thing of expanding the tree nodes will reveal the detailed trace information collected during the run: ![Screenshot showing some expanded output nodes](./Images/4.png) +/// caption +Screenshot showing some expanded output nodes +/// You can also expand the current page of trace information using the "expand" button or the drop down menu next to it. (Once the expand button has been pressed @@ -94,6 +106,9 @@ If you load another demo here (e.g. "Water Jug Demo") and then type `run 20` you will see both sets of windows updating as both agents run. ![Screenshot showing multiple debugger windows, one per agent](./Images/5.png) +/// caption +Screenshot showing multiple debugger windows, one per agent +/// The relationship between a top level debugger window (a frame) and the agent is pretty loose. For instance, we can switch the second window to observe the first @@ -129,6 +144,9 @@ get a warning that there's a local kernel running. Say "OK" to shut that down. You'll see a dialog like this: ![Screenshot of remote kernel connection dialog](./Images/6.png) +/// caption +Screenshot of remote kernel connection dialog +/// This allows you to enter an IP address (for a truly remote machine) or a different port number (which requires a change to the kernel you are connecting to). For this @@ -161,6 +179,9 @@ To walkthrough this demonstration, start by launching the [Java version of Towers of Hanoi](../../downloads/examples_and_unsupported/towers_of_hanoi.md): ![Screenshot showing Java Towers of Hanoi starting position](./Images/7.png) +/// caption +Screenshot showing Java Towers of Hanoi starting position +/// The simulation starts an embedded Soar kernel when it's launched. You can run the environment by pressing "run"/"stop" as you'd expect. @@ -173,12 +194,18 @@ You should now see the name of the agent (in the title bar of the debugger) chan to "remote TOH" like this: ![Screenshot of debugger showing name of agent as "remote TOH"](./Images/8.png) +/// caption +Screenshot of debugger showing name of agent as "remote TOH" +/// At this point pressing run in the environment will generate trace output in the debugger. (The agent starts at watch 0 in this simulation so you just see `write` statements from productions). ![Screenshot of debugger output for TOH](./Images/9.png) +/// caption +Screenshot of debugger output for TOH +/// Pressing "stop" in the environment again stops the run. So far this is simple enough. @@ -255,10 +282,16 @@ You can also create your own preferred window layout. To start this process, rig click on a window in the debugger. The context menu will either look like this: ![Screenshot of the debugger's Window context menu](./Images/10.png) +/// caption +Screenshot of the debugger's Window context menu +/// Or it will offer this menu as a "Window" pop out on the context menu like this: ![Screenshot of the debugger's Window context menu as a child of another context menu](./Images/11.png) +/// caption +Screenshot of the debugger's Window context menu as a child of another context menu +/// This window menu allows you to customize the collection of windows by adding, removing or replacing windows. The types of windows you can add is based on the list @@ -266,6 +299,9 @@ of modules loaded into the debugger and should grow in time. Right now there are just five: ![Screenshot of "Select a New Window" dialog](./Images/12.png) +/// caption +Screenshot of "Select a New Window" dialog +/// Creating a new layout can take a while as we don't yet have a "Move Window" option. This is something to be added in the future. Once you've created a new layout it @@ -290,6 +326,9 @@ automatically updating windows (top right in the default layout) brings up these properties: ![Screnshot of window properties dialog](./Images/13.png) +/// caption +Screnshot of window properties dialog +/// By adjusting these properties you can allow the results to collect in the window rather than being cleared each time a command is executed or you can have a window diff --git a/docs/tutorials/soar_tutorial/01.md b/docs/tutorials/soar_tutorial/01.md index e8070935..506e97fd 100644 --- a/docs/tutorials/soar_tutorial/01.md +++ b/docs/tutorials/soar_tutorial/01.md @@ -39,6 +39,9 @@ somewhat different, depending on the features added since this document was written. ![The Soar Debugger](Images/01/image1.png) +/// caption +The Soar Debugger +/// The large window to the left is called the Interaction window (above). During Soar execution, all debugging information and print statements @@ -54,6 +57,9 @@ be entered by typing them into the command box, or by clicking the buttons ![Debugger Command Interface](Images/01/image2.png) +/// caption +Debugger Command Interface +/// ### Hello-World Rule: English diff --git a/docs/tutorials/soar_tutorial/07.md b/docs/tutorials/soar_tutorial/07.md index 978fc73c..c5ca821e 100644 --- a/docs/tutorials/soar_tutorial/07.md +++ b/docs/tutorials/soar_tutorial/07.md @@ -66,6 +66,9 @@ If you have [graphviz](http://graphviz.org) and DOT installed it should launch your system viewer to show a diagram similar to: ![Example visualization of SMem](Images/07/image1.png) +/// caption +Example visualization of SMem +/// Now that we have seen the contents of semantic memory, you can confirm that none of this knowledge is present in any of the agent’s other memories. For instance, diff --git a/docs/tutorials/soar_tutorial/08.md b/docs/tutorials/soar_tutorial/08.md index 0e0ef95f..8695e415 100644 --- a/docs/tutorials/soar_tutorial/08.md +++ b/docs/tutorials/soar_tutorial/08.md @@ -61,6 +61,9 @@ If you have [graphviz](http://graphviz.org) and DOT installed, it should launch your system viewer to show a diagram similar to: ![Example visualization of episodic memory](Images/08/image1.png) +/// caption +Example visualization of episodic memory +/// From both the trace output as well as the Graphviz rendering we can see that episodic memory has stored most of the top-state of the agent’s @@ -206,12 +209,18 @@ is the value of the _query_ command, as described above: Or, visually: ![Example cue](Images/08/image2.png) +/// caption +Example cue +/// This cue has three leaf WMEs: (`N1 ^feature value`), (`N2 ^sub-feature value2`), and (`N2 ^id N3`). Now consider the following episode: ![Episode to match cue](Images/08/image3.png) +/// caption +Episode to match cue +/// The first leaf WME of the cue, (`N1 ^feature value`), is not satisfied by this episode, as there is no (`E1 ^feature value`) WME: (`E1 ^feature2 value`) has a diff --git a/docs/workshops/19.md b/docs/workshops/19.md index 458c7265..f49c0fbc 100644 --- a/docs/workshops/19.md +++ b/docs/workshops/19.md @@ -5,6 +5,9 @@ May 20th-23rd, 1999 Ann Arbor, MI ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/19/group_photo.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/20/index.md b/docs/workshops/20/index.md index 4e917020..8b2f52a7 100644 --- a/docs/workshops/20/index.md +++ b/docs/workshops/20/index.md @@ -7,6 +7,9 @@ Los Angeles, CA [Original Proceedings Page](index_original.html) ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/20/group.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/23.md b/docs/workshops/23.md index 6894a406..a7a8e62f 100644 --- a/docs/workshops/23.md +++ b/docs/workshops/23.md @@ -5,6 +5,9 @@ June 23rd-27th, 2003 Ann Arbor, Michigan ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/23/group_photo.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/24/index.md b/docs/workshops/24/index.md index 8b95368e..fb348561 100644 --- a/docs/workshops/24/index.md +++ b/docs/workshops/24/index.md @@ -7,6 +7,9 @@ Ann Arbor, MI [Original announcement page](24_announcement.html) ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/24/group_photo.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/25/index.md b/docs/workshops/25/index.md index 70259655..35de6954 100644 --- a/docs/workshops/25/index.md +++ b/docs/workshops/25/index.md @@ -7,6 +7,9 @@ Ann Arbor, MI [Original announcement page](25_announcement.html) ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/25/group_photo.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/26/index.md b/docs/workshops/26/index.md index a5b87cef..4b3cbbf9 100644 --- a/docs/workshops/26/index.md +++ b/docs/workshops/26/index.md @@ -7,6 +7,9 @@ Ann Arbor, Michigan [Original announcement page](26_announcement.html) ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/26/group_photo.gif) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/27.md b/docs/workshops/27.md index 46b3521a..681351e1 100644 --- a/docs/workshops/27.md +++ b/docs/workshops/27.md @@ -5,6 +5,9 @@ May 21-25, 2007 Ann Arbor, Michigan ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/27/27th.jpg) +/// caption +Participant group photo +/// ## Schedule diff --git a/docs/workshops/28.md b/docs/workshops/28.md index c6989c30..8e061c9c 100644 --- a/docs/workshops/28.md +++ b/docs/workshops/28.md @@ -5,6 +5,9 @@ May 4th-7th, 2008 Ann Arbor, MI ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/28/Workshop28.jpg) +/// caption +Participant group photo +/// | Presenter | Title | Links | |------------------|--------------------------------------------------------------|------------------------------------------------------------| diff --git a/docs/workshops/29.md b/docs/workshops/29.md index 6a0df0bb..926d57a3 100644 --- a/docs/workshops/29.md +++ b/docs/workshops/29.md @@ -5,6 +5,9 @@ June 22-26, 2009 Ann Arbor, MI ![Participant group photo](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/29/workshop29.png) +/// caption +Participant group photo +/// | Presenter | Title | Links | |-----------|-------|-------| diff --git a/docs/workshops/31.md b/docs/workshops/31.md index 9cec6489..a9ef7bf0 100644 --- a/docs/workshops/31.md +++ b/docs/workshops/31.md @@ -5,6 +5,9 @@ June 13th-17th, 2011 3270 Beyster Building, North Campus, University of Michigan ![Participant group photo in front of Beyster building, 2011](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/31/group.jpg) +/// caption +Participant group photo in front of Beyster building, 2011 +/// ## Schedule diff --git a/docs/workshops/32.md b/docs/workshops/32.md index 35bae079..ce5a2b73 100644 --- a/docs/workshops/32.md +++ b/docs/workshops/32.md @@ -7,6 +7,9 @@ June 18th-22nd, 2012 Room 1670 ![Participant group photo in front of Beyster building with arms raised (making waves), 2012](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/32/group.jpg) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2012 +/// ## Schedule diff --git a/docs/workshops/33.md b/docs/workshops/33.md index 5df1c65c..4ed44a7c 100644 --- a/docs/workshops/33.md +++ b/docs/workshops/33.md @@ -7,8 +7,14 @@ June 3rd-6th, 2013 Room 1670 ![Participant group photo in front of Beyster building, 2013](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/33/Soar_Wkshp_2013_hr.jpg) +/// caption +Participant group photo in front of Beyster building, 2013 +/// ![Participant group photo in front of Beyster building with arms raised (making waves), 2013](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/33/group.jpg) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2013 +/// ## Schedule diff --git a/docs/workshops/34.md b/docs/workshops/34.md index 837901bb..f4c24f8a 100644 --- a/docs/workshops/34.md +++ b/docs/workshops/34.md @@ -5,8 +5,14 @@ June 16th-20th, 2014 3270 Beyster Building, North Campus, University of Michigan ![Participant group photo in front of Beyster building, 2014](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/34/Soar_Wkshp_2014_hr.jpg) +/// caption +Participant group photo in front of Beyster building, 2014 +/// ![Participant group photo in front of Beyster building with arms raised (making waves), 2014](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/34/Soar_Wkshp_2014_wave_hr.jpg) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2014 +/// ## Schedule diff --git a/docs/workshops/35.md b/docs/workshops/35.md index 26069bad..5cff37f4 100644 --- a/docs/workshops/35.md +++ b/docs/workshops/35.md @@ -5,6 +5,9 @@ June 1st-5th, 2015 3270 Beyster Building, North Campus, University of Michigan ![Participant group photo in front of Beyster building with arms raised (making waves), 2015](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/35/workshop2015_wave.png) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2015 +/// ## Schedule diff --git a/docs/workshops/36.md b/docs/workshops/36.md index 636972d5..d5d6bd84 100644 --- a/docs/workshops/36.md +++ b/docs/workshops/36.md @@ -5,6 +5,9 @@ June 6th-10th, 2016 3270 Beyster Building, North Campus, University of Michigan ![Participant group photo in front of Beyster building with arms raised (making waves), 2016](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/36/workshop2016_wave.jpg) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2016 +/// ## Schedule diff --git a/docs/workshops/37.md b/docs/workshops/37.md index 6b0149ca..2633b768 100644 --- a/docs/workshops/37.md +++ b/docs/workshops/37.md @@ -5,8 +5,14 @@ June 5th-9th, 2017 3270 Beyster Building, North Campus, University of Michigan ![Participant group photo in front of Beyster building, 2017](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/37/2017_Workshop.jpg) +/// caption +Participant group photo in front of Beyster building, 2017 +/// ![Participant group photo in front of Beyster building with arms raised (making waves), 2017](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/37/2017_Workshop_wave.jpg) +/// caption +Participant group photo in front of Beyster building with arms raised (making waves), 2017 +/// ## Schedule diff --git a/docs/workshops/41.md b/docs/workshops/41.md index d519acbf..70220d0d 100644 --- a/docs/workshops/41.md +++ b/docs/workshops/41.md @@ -7,6 +7,9 @@ June 14th-15th, 2021 Also attended virtually via Zoom ![Participant group photo (Zoom screenshot) with arms raised (making waves), 2021](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/41/SW.png) +/// caption +Participant group photo (Zoom screenshot) with arms raised (making waves), 2021 +/// ## Schedule diff --git a/docs/workshops/45.md b/docs/workshops/45.md index bd4fe188..c298fbcd 100644 --- a/docs/workshops/45.md +++ b/docs/workshops/45.md @@ -12,8 +12,14 @@ of Princeton Neuroscience Institute [YouTube playlist](https://www.youtube.com/playlist?list=PLoKKYskiirycWPYbSXGiKrqofzR591iJu) ![Zoom screenshot of participants with arms raised (making waves), 2025](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/45/2025_workshop_wave_zoom.png) +/// caption +Zoom screenshot of participants with arms raised (making waves), 2025 +/// ![Participant group photo with arms raised (making waves), 2025](https://raw.githubusercontent.com/SoarGroup/website-downloads/main/workshops/45/2025_Workshop_wave.png) +/// caption +Participant group photo with arms raised (making waves), 2025 +/// ## Schedule diff --git a/hooks.py b/hooks.py deleted file mode 100644 index 1b0ebd11..00000000 --- a/hooks.py +++ /dev/null @@ -1,52 +0,0 @@ -# https://www.mkdocs.org/user-guide/configuration/#hooks - -import re - -from pathlib import Path -from mkdocs.plugins import BasePlugin - -# Convert image links to figures: modified from https://github.com/Jackiexiao/mkdocs-img2figv2-plugin -# to support absolute URLs - -IMAGE_REGEX = re.compile(r'!\[(.*?)\]\((.*?)\)(\{[^\}]*\})?', flags=re.IGNORECASE) - -def on_page_markdown(markdown, page, **kwargs): - modifier = get_image_link_modifier(page.file.abs_src_path) - markdown = re.sub(IMAGE_REGEX, modifier, markdown) - return markdown - -def get_image_link_modifier(file_path): - def modify_match(match): - caption, image_link, attr_list = match.groups() - - is_absolute = image_link.startswith('http://') or image_link.startswith('https://') - is_explicit_relative = image_link.startswith('./') or image_link.startswith('../') - - # If the image link is underspecified, make it relative to the containing folder - # TODO: this is really confusing because an index.md in a folder will require - # different paths; re-do links and get rid of this. - if not (is_absolute or is_explicit_relative): - image_link = ('..' / Path(image_link)).as_posix() - if attr_list: - attr_list = attr_list.replace('{', '').replace('}', '') - else: - attr_list = '' - - if not image_link.endswith(".svg"): - image_element = rf'{caption}' - else: - # load the entire SVG file and paste inline so that styling works properly - absolute_path = Path(Path(file_path), Path(image_link)).resolve() - image_element = absolute_path.read_text() - # for now, we're not copying the attributes - if attr_list: - raise ValueError(f"Attributes on SVG images have not been implemented! See hooks.py. Received: '{attr_list}' while processing {file_path}") - - return ( - r'

' - rf' {image_element}' - rf'
{caption}
' - r'
' - ) - return modify_match - diff --git a/main.py b/main.py index d05e61ef..f0536c32 100644 --- a/main.py +++ b/main.py @@ -5,13 +5,21 @@ def define_env(env): "Defines macros for Mkdocs-Macros" + def soar_version(): + # mkdocs-macros exposes `extra` values via env.variables; Zensical's + # macros shim only exposes them via env.conf["extra"]. + try: + return env.variables["soar_version"] + except (AttributeError, KeyError): + return env.conf["extra"]["soar_version"] + @env.macro def tutorial_wip_warning(file_name): return ( "# 🚧 Under Construction 🚧\n The HTML version of the tutorial " "is currently under construction; in particular, the figure " "annotations are missing. You may wish to view the PDF version " - f"[here](https://github.com/SoarGroup/Soar/releases/download/releases%2F{env.variables['soar_version']}/{file_name}) " + f"[here](https://github.com/SoarGroup/Soar/releases/download/releases%2F{soar_version()}/{file_name}) " "instead." ) diff --git a/mkdocs.yml b/mkdocs.yml index 9026c1ae..98965f0e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,11 +1,12 @@ site_name: Soar Home repo_url: https://github.com/SoarGroup/SoarGroup.github.io repo_name: Website Source -copyright: Copyright © SoarGroup 2024 +copyright: Copyright © SoarGroup 2026 edit_uri: edit/main/docs/ theme: name: material + variant: modern custom_dir: overrides locale: en logo: Images/soar.png @@ -55,7 +56,6 @@ theme: extra_javascript: - javascript/mathjax.js - - https://polyfill.io/v3/polyfill.min.js?features=es6 - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js markdown_extensions: @@ -65,8 +65,6 @@ markdown_extensions: - tables - toc: permalink: true - - mdx_math - - fenced_code - pymdownx.highlight: anchor_linenums: true line_spans: __span @@ -80,6 +78,7 @@ markdown_extensions: auto_append: - includes/abbreviations.md - pymdownx.superfences + - pymdownx.blocks.caption - attr_list - md_in_html - pymdownx.arithmatex: @@ -110,130 +109,130 @@ nav: - Downloads: - downloads/index.md - Soar: - - downloads/soar/index.md - - Latest: downloads/soar/latest.md - - Archive: downloads/soar/archive.md - - JSoar: downloads/soar/jsoar.md + - downloads/soar/index.md + - Latest: downloads/soar/latest.md + - Archive: downloads/soar/archive.md + - JSoar: downloads/soar/jsoar.md - Agents: - - downloads/agents/index.md - - 15-Puzzle: downloads/agents/15-puzzle.md - - 8-Puzzle: downloads/agents/8-puzzle.md - - Algebra Solver: downloads/agents/algebra_solver.md - - Arithmetic: downloads/agents/arithmetic.md - - Arithmetic (with Semantic Memory): downloads/agents/arithmetic_(with_semantic_memory).md - - Blocks-World (Hierarchical Look-Ahead): downloads/agents/blocks-world_(hierarchical_look-ahead).md - - Blocks-World (Hierarchical): downloads/agents/blocks-world_(hierarchical).md - - Blocks-World (Look-Ahead with RL): downloads/agents/blocks-world_(look-ahead_with_rl).md - - Blocks-World (Look-Ahead): downloads/agents/blocks-world_(look-ahead).md - - Blocks-World (Reinforcement Learning): downloads/agents/blocks-world_(reinforcement_learning).md - - Blocks-World (Simple): downloads/agents/blocks-world_(simple).md - - Blocks-World (Subgoaling with RL): downloads/agents/blocks-world_(subgoaling_with_rl).md - - Blocks-World (Subgoaling): downloads/agents/blocks-world_(subgoaling).md - - Counting Agent: downloads/agents/counting_agent.md - - Eaters (Advanced Move): downloads/agents/eaters_(advanced_move).md - - Eaters (Hello World Operator): downloads/agents/eaters_(hello_world_operator).md - - Eaters (Hello World Rule): downloads/agents/eaters_(hello_world_rule).md - - Eaters (Jump and Move): downloads/agents/eaters_(jump_and_move).md - - Eaters (Jump): downloads/agents/eaters_(jump).md - - Eaters (Move North 2): downloads/agents/eaters_(move_north_2).md - - Eaters (Move North): downloads/agents/eaters_(move_north).md - - Eaters (Move To Food): downloads/agents/eaters_(move_to_food).md - - Eaters (Move): downloads/agents/eaters_(move).md - - Eaters (Semantic Error Example): downloads/agents/eaters_(semantic_error_example).md - - Eaters (Syntax Error Example): downloads/agents/eaters_(syntax_error_example).md - - Episodic Memory Counting Agent: downloads/agents/episodic_memory_counting_agent.md - - Episodic Memory Tutorial Agent: downloads/agents/episodic_memory_tutorial_agent.md - - Graph Search: downloads/agents/graph_search.md - - Graph Search (with Semantic Memory): downloads/agents/graph_search_(with_semantic_memory).md - - Infinite Mario RL: downloads/agents/infinite_mario_rl.md - - Knowledge Base Agent: downloads/agents/knowledge_base_agent.md - - Left-Right Reinforcement Learning Agent: downloads/agents/left-right_reinforcement_learning_agent.md - - Missionaries and Cannibals (Planning): downloads/agents/missionaries_and_cannibals_(planning).md - - Missionaries and Cannibals (Simple): downloads/agents/missionaries_and_cannibals_(simple).md - - Reinforcement Learning Unit Test: downloads/agents/reinforcement_learning_unit_test.md - - Semantic Memory Tutorial Agent: downloads/agents/semantic_memory_tutorial_agent.md - - Soar 7 Agents: downloads/agents/soar_7_agents.md - - TankSoar (Mapping): downloads/agents/tanksoar_(mapping).md - - TankSoar (Obscure Bot): downloads/agents/tanksoar_(obscure_bot).md - - TankSoar (Simple Sound): downloads/agents/tanksoar_(simple_sound).md - - TankSoar (Simple): downloads/agents/tanksoar_(simple).md - - TankSoar (Wander): downloads/agents/tanksoar_(wander).md - - Taxi (Hierarchical Reinforcement Learning): downloads/agents/taxi_(hierarchical_reinforcement_learning).md - - Taxi (Reinforcement Learning): downloads/agents/taxi_(reinforcement_learning).md - - TextIO Example: downloads/agents/textio_example.md - - Tower of Hanoi (Recursive): downloads/agents/tower_of_hanoi_(recursive).md - - Tower of Hanoi (Simple): downloads/agents/tower_of_hanoi_(simple).md - - Water Jug (Hierarchical Task Decomposition): downloads/agents/water_jug_(hierarchical_task_decomposition).md - - Water Jug (Look-Ahead with State Evaluation): downloads/agents/water_jug_(look-ahead_with_state_evaluation).md - - Water Jug (Look-Ahead): downloads/agents/water_jug_(look-ahead).md - - Water Jug (Reinforcement Learning): downloads/agents/water_jug_(reinforcement_learning).md - - Water Jug (Simple): downloads/agents/water_jug_(simple).md + - downloads/agents/index.md + - 15-Puzzle: downloads/agents/15-puzzle.md + - 8-Puzzle: downloads/agents/8-puzzle.md + - Algebra Solver: downloads/agents/algebra_solver.md + - Arithmetic: downloads/agents/arithmetic.md + - Arithmetic (with Semantic Memory): downloads/agents/arithmetic_(with_semantic_memory).md + - Blocks-World (Hierarchical Look-Ahead): downloads/agents/blocks-world_(hierarchical_look-ahead).md + - Blocks-World (Hierarchical): downloads/agents/blocks-world_(hierarchical).md + - Blocks-World (Look-Ahead with RL): downloads/agents/blocks-world_(look-ahead_with_rl).md + - Blocks-World (Look-Ahead): downloads/agents/blocks-world_(look-ahead).md + - Blocks-World (Reinforcement Learning): downloads/agents/blocks-world_(reinforcement_learning).md + - Blocks-World (Simple): downloads/agents/blocks-world_(simple).md + - Blocks-World (Subgoaling with RL): downloads/agents/blocks-world_(subgoaling_with_rl).md + - Blocks-World (Subgoaling): downloads/agents/blocks-world_(subgoaling).md + - Counting Agent: downloads/agents/counting_agent.md + - Eaters (Advanced Move): downloads/agents/eaters_(advanced_move).md + - Eaters (Hello World Operator): downloads/agents/eaters_(hello_world_operator).md + - Eaters (Hello World Rule): downloads/agents/eaters_(hello_world_rule).md + - Eaters (Jump and Move): downloads/agents/eaters_(jump_and_move).md + - Eaters (Jump): downloads/agents/eaters_(jump).md + - Eaters (Move North 2): downloads/agents/eaters_(move_north_2).md + - Eaters (Move North): downloads/agents/eaters_(move_north).md + - Eaters (Move To Food): downloads/agents/eaters_(move_to_food).md + - Eaters (Move): downloads/agents/eaters_(move).md + - Eaters (Semantic Error Example): downloads/agents/eaters_(semantic_error_example).md + - Eaters (Syntax Error Example): downloads/agents/eaters_(syntax_error_example).md + - Episodic Memory Counting Agent: downloads/agents/episodic_memory_counting_agent.md + - Episodic Memory Tutorial Agent: downloads/agents/episodic_memory_tutorial_agent.md + - Graph Search: downloads/agents/graph_search.md + - Graph Search (with Semantic Memory): downloads/agents/graph_search_(with_semantic_memory).md + - Infinite Mario RL: downloads/agents/infinite_mario_rl.md + - Knowledge Base Agent: downloads/agents/knowledge_base_agent.md + - Left-Right Reinforcement Learning Agent: downloads/agents/left-right_reinforcement_learning_agent.md + - Missionaries and Cannibals (Planning): downloads/agents/missionaries_and_cannibals_(planning).md + - Missionaries and Cannibals (Simple): downloads/agents/missionaries_and_cannibals_(simple).md + - Reinforcement Learning Unit Test: downloads/agents/reinforcement_learning_unit_test.md + - Semantic Memory Tutorial Agent: downloads/agents/semantic_memory_tutorial_agent.md + - Soar 7 Agents: downloads/agents/soar_7_agents.md + - TankSoar (Mapping): downloads/agents/tanksoar_(mapping).md + - TankSoar (Obscure Bot): downloads/agents/tanksoar_(obscure_bot).md + - TankSoar (Simple Sound): downloads/agents/tanksoar_(simple_sound).md + - TankSoar (Simple): downloads/agents/tanksoar_(simple).md + - TankSoar (Wander): downloads/agents/tanksoar_(wander).md + - Taxi (Hierarchical Reinforcement Learning): downloads/agents/taxi_(hierarchical_reinforcement_learning).md + - Taxi (Reinforcement Learning): downloads/agents/taxi_(reinforcement_learning).md + - TextIO Example: downloads/agents/textio_example.md + - Tower of Hanoi (Recursive): downloads/agents/tower_of_hanoi_(recursive).md + - Tower of Hanoi (Simple): downloads/agents/tower_of_hanoi_(simple).md + - Water Jug (Hierarchical Task Decomposition): downloads/agents/water_jug_(hierarchical_task_decomposition).md + - Water Jug (Look-Ahead with State Evaluation): downloads/agents/water_jug_(look-ahead_with_state_evaluation).md + - Water Jug (Look-Ahead): downloads/agents/water_jug_(look-ahead).md + - Water Jug (Reinforcement Learning): downloads/agents/water_jug_(reinforcement_learning).md + - Water Jug (Simple): downloads/agents/water_jug_(simple).md - Domains: - - downloads/domains/index.md - - Dice: downloads/domains/dice.md - - Eaters: downloads/domains/eaters.md - - General Game Player Translator: downloads/domains/general_game_player_translator.md - - Infinite Mario RL: downloads/domains/infinite_mario_rl.md - - PDDL Translator: downloads/domains/pddl_translator.md - - RoomsWorld: downloads/domains/roomsworld.md - - Soar QnA: downloads/domains/soar_qna.md - - TankSoar: downloads/domains/tanksoar.md - - Taxi: downloads/domains/taxi.md - - WordNet WSD: downloads/domains/wordnet_wsd.md - - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md - - Eaters: downloads/domains/eaters.md - - General Game Player Translator: downloads/domains/general_game_player_translator.md - - Infinite Mario RL: downloads/domains/infinite_mario_rl.md - - PDDL Translator: downloads/domains/pddl_translator.md - - RoomsWorld: downloads/domains/roomsworld.md - - Soar QnA: downloads/domains/soar_qna.md - - SoarText-IO: downloads/domains/soartext-io.md - - TankSoar: downloads/domains/tanksoar.md - - Taxi: downloads/domains/taxi.md - - WordNet WSD: downloads/domains/wordnet_wsd.md - - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md - - Eaters: downloads/domains/eaters.md - - General Game Player Translator: downloads/domains/general_game_player_translator.md - - Infinite Mario RL: downloads/domains/infinite_mario_rl.md - - PDDL Translator: downloads/domains/pddl_translator.md - - RoomsWorld: downloads/domains/roomsworld.md - - Soar QnA: downloads/domains/soar_qna.md - - SoarText-IO: downloads/domains/soartext-io.md - - TankSoar: downloads/domains/tanksoar.md - - Taxi: downloads/domains/taxi.md - - WordNet WSD: downloads/domains/wordnet_wsd.md - - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md + - downloads/domains/index.md + - Dice: downloads/domains/dice.md + - Eaters: downloads/domains/eaters.md + - General Game Player Translator: downloads/domains/general_game_player_translator.md + - Infinite Mario RL: downloads/domains/infinite_mario_rl.md + - PDDL Translator: downloads/domains/pddl_translator.md + - RoomsWorld: downloads/domains/roomsworld.md + - Soar QnA: downloads/domains/soar_qna.md + - TankSoar: downloads/domains/tanksoar.md + - Taxi: downloads/domains/taxi.md + - WordNet WSD: downloads/domains/wordnet_wsd.md + - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md + - Eaters: downloads/domains/eaters.md + - General Game Player Translator: downloads/domains/general_game_player_translator.md + - Infinite Mario RL: downloads/domains/infinite_mario_rl.md + - PDDL Translator: downloads/domains/pddl_translator.md + - RoomsWorld: downloads/domains/roomsworld.md + - Soar QnA: downloads/domains/soar_qna.md + - SoarText-IO: downloads/domains/soartext-io.md + - TankSoar: downloads/domains/tanksoar.md + - Taxi: downloads/domains/taxi.md + - WordNet WSD: downloads/domains/wordnet_wsd.md + - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md + - Eaters: downloads/domains/eaters.md + - General Game Player Translator: downloads/domains/general_game_player_translator.md + - Infinite Mario RL: downloads/domains/infinite_mario_rl.md + - PDDL Translator: downloads/domains/pddl_translator.md + - RoomsWorld: downloads/domains/roomsworld.md + - Soar QnA: downloads/domains/soar_qna.md + - SoarText-IO: downloads/domains/soartext-io.md + - TankSoar: downloads/domains/tanksoar.md + - Taxi: downloads/domains/taxi.md + - WordNet WSD: downloads/domains/wordnet_wsd.md + - WordNet WSD (with Parse Trees): downloads/domains/wordnet_wsd_(with_parse_trees).md - Agent Development Tools: - - downloads/agent_development_tools/index.md - - Episodic Memory Size Tool: downloads/agent_development_tools/episodic_memory_size_tool.md - - QuickLink Input Simulator: downloads/agent_development_tools/quicklink_input_simulator.md - - Soar Data Collector: downloads/agent_development_tools/soar_data_collector.md - - Soar Debugger: downloads/agent_development_tools/soar_debugger.md - - SoarEditor: downloads/agent_development_tools/soareditor.md - - SoarIDE: downloads/agent_development_tools/soaride.md - - SoarUnit: downloads/agent_development_tools/soarunit.md - - State2Dot: downloads/agent_development_tools/state2dot.md - - SublimeText Soar Tools Package: downloads/agent_development_tools/sublimetext_soar_tools_package/index.md - - UltraEdit Syntax Coloring Wordfile: downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md - - Vim Soar Plug-In: downloads/agent_development_tools/vim_soar_plug-in.md - - VisualSoar: downloads/agent_development_tools/visualsoar.md + - downloads/agent_development_tools/index.md + - Episodic Memory Size Tool: downloads/agent_development_tools/episodic_memory_size_tool.md + - QuickLink Input Simulator: downloads/agent_development_tools/quicklink_input_simulator.md + - Soar Data Collector: downloads/agent_development_tools/soar_data_collector.md + - Soar Debugger: downloads/agent_development_tools/soar_debugger.md + - SoarEditor: downloads/agent_development_tools/soareditor.md + - SoarIDE: downloads/agent_development_tools/soaride.md + - SoarUnit: downloads/agent_development_tools/soarunit.md + - State2Dot: downloads/agent_development_tools/state2dot.md + - SublimeText Soar Tools Package: downloads/agent_development_tools/sublimetext_soar_tools_package/index.md + - UltraEdit Syntax Coloring Wordfile: downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md + - Vim Soar Plug-In: downloads/agent_development_tools/vim_soar_plug-in.md + - VisualSoar: downloads/agent_development_tools/visualsoar.md - Examples and Unsupported: - - downloads/examples_and_unsupported/index.md - - C++ Command Line Filter: downloads/examples_and_unsupported/cpp_command_line_filter_example.md - - Towers of Hanoi: downloads/examples_and_unsupported/towers_of_hanoi.md - - C++ Logger: downloads/examples_and_unsupported/c++_logger.md - - C# Interface Example: downloads/examples_and_unsupported/csharp_interface_example.md - - Java Logger: downloads/examples_and_unsupported/java_logger.md - - Missionaries and Cannibals: downloads/examples_and_unsupported/missionaries_and_cannibals.md - - PHP Interface Example: downloads/examples_and_unsupported/php_interface_example.md - - Python Interface Example: downloads/examples_and_unsupported/python_interface_example.md - - RL Command Line Interface: downloads/examples_and_unsupported/rl_command_line_interface.md - - Soar Obfuscator: downloads/examples_and_unsupported/soar_obfuscator.md - - Soar on iOS: downloads/examples_and_unsupported/soar_on_ios.md - - Soar Scratch Pad: downloads/examples_and_unsupported/soar_scratch_pad.md - - Tcl Command Line Filter Example: downloads/examples_and_unsupported/tcl_command_line_filter_example.md - - Tower of Hanoi SML Example: downloads/examples_and_unsupported/tower_of_hanoi_sml_example.md - - Working Memory Activation Tracker: downloads/examples_and_unsupported/working_memory_activation_tracker.md + - downloads/examples_and_unsupported/index.md + - C++ Command Line Filter: downloads/examples_and_unsupported/cpp_command_line_filter_example.md + - Towers of Hanoi: downloads/examples_and_unsupported/towers_of_hanoi.md + - C++ Logger: downloads/examples_and_unsupported/c++_logger.md + - C# Interface Example: downloads/examples_and_unsupported/csharp_interface_example.md + - Java Logger: downloads/examples_and_unsupported/java_logger.md + - Missionaries and Cannibals: downloads/examples_and_unsupported/missionaries_and_cannibals.md + - PHP Interface Example: downloads/examples_and_unsupported/php_interface_example.md + - Python Interface Example: downloads/examples_and_unsupported/python_interface_example.md + - RL Command Line Interface: downloads/examples_and_unsupported/rl_command_line_interface.md + - Soar Obfuscator: downloads/examples_and_unsupported/soar_obfuscator.md + - Soar on iOS: downloads/examples_and_unsupported/soar_on_ios.md + - Soar Scratch Pad: downloads/examples_and_unsupported/soar_scratch_pad.md + - Tcl Command Line Filter Example: downloads/examples_and_unsupported/tcl_command_line_filter_example.md + - Tower of Hanoi SML Example: downloads/examples_and_unsupported/tower_of_hanoi_sml_example.md + - Working Memory Activation Tracker: downloads/examples_and_unsupported/working_memory_activation_tracker.md - Tutorials: - tutorials/index.md - Official Soar Tutorials: @@ -266,51 +265,51 @@ nav: - development/index.md - Technical FAQ: development/SoarTechnicalFAQ.md - Robot Operating System (ROS): - - ROS 1: development/BuildingSoarRos.md - - ROS 2: https://github.com/THA-Embedded-Systems-Lab/soar_ros + - ROS 1: development/BuildingSoarRos.md + - ROS 2: https://github.com/THA-Embedded-Systems-Lab/soar_ros - Soar Agents: - - Design Dogma: development/agents/DesignDogma.md - - Soar Programmer's Guide: development/agents/SoarProgrammersGuide.md - - SML Output Link Guide: development/agents/SMLOutputLinkGuide.md - - How to compile SML Clients: development/agents/HowToCompileSmlClients.md + - Design Dogma: development/agents/DesignDogma.md + - Soar Programmer's Guide: development/agents/SoarProgrammersGuide.md + - SML Output Link Guide: development/agents/SMLOutputLinkGuide.md + - How to compile SML Clients: development/agents/HowToCompileSmlClients.md - Soar Kernel: - - Basic Kernel Terminology: development/soar/BasicKernelTerminology.md - - CLI Parsing Code: development/soar/CLIParsingCode.md - - IO and Reward Links: development/soar/IOAndRewardLinks.md - - Memory Leak Debugging with Visual Studio: development/soar/MemoryLeakDebuggingWithVisualStudio.md - - Threads in SML: development/soar/ThreadsInSML.md - - Timers: development/soar/Timers.md - - Waterfall: development/soar/Waterfall.md + - Basic Kernel Terminology: development/soar/BasicKernelTerminology.md + - CLI Parsing Code: development/soar/CLIParsingCode.md + - IO and Reward Links: development/soar/IOAndRewardLinks.md + - Memory Leak Debugging with Visual Studio: development/soar/MemoryLeakDebuggingWithVisualStudio.md + - Threads in SML: development/soar/ThreadsInSML.md + - Timers: development/soar/Timers.md + - Waterfall: development/soar/Waterfall.md - Workshops: - - workshops/index.md - - workshops/45.md - - workshops/44.md - - workshops/43.md - - workshops/42.md - - workshops/41.md - - workshops/40.md - - workshops/39.md - - workshops/38.md - - workshops/37.md - - workshops/36.md - - workshops/35.md - - workshops/34.md - - workshops/33.md - - workshops/32.md - - workshops/31.md - - workshops/30.md - - workshops/29.md - - workshops/28.md - - workshops/27.md - - workshops/26/index.md - - workshops/25/index.md - - workshops/24/index.md - - workshops/23.md - - workshops/22.md - - workshops/21.md - - workshops/20/index.md - - workshops/19.md - - workshops/17.md + - workshops/index.md + - workshops/45.md + - workshops/44.md + - workshops/43.md + - workshops/42.md + - workshops/41.md + - workshops/40.md + - workshops/39.md + - workshops/38.md + - workshops/37.md + - workshops/36.md + - workshops/35.md + - workshops/34.md + - workshops/33.md + - workshops/32.md + - workshops/31.md + - workshops/30.md + - workshops/29.md + - workshops/28.md + - workshops/27.md + - workshops/26/index.md + - workshops/25/index.md + - workshops/24/index.md + - workshops/23.md + - workshops/22.md + - workshops/21.md + - workshops/20/index.md + - workshops/19.md + - workshops/17.md - Support: - support/index.md - Reference: @@ -352,8 +351,4 @@ plugins: - macros: on_error_fail: true on_undefined: strict - - tags: - tags_file: home/tags.md - -hooks: - - hooks.py + - tags diff --git a/overrides/partials/copyright.html b/overrides/partials/copyright.html index 3e059ee4..ff7d8430 100644 --- a/overrides/partials/copyright.html +++ b/overrides/partials/copyright.html @@ -24,18 +24,15 @@ + + {% endif %} {% if not config.extra.generator == false %} Made with + Zensical. {% endif %} Special thanks to + Moritz Schmidt + for his work on the website! + diff --git a/requirements.txt b/requirements.txt index da3260bd..b03ded70 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,4 @@ -mkdocs-material==9.* -mkdocs-material-extensions==1.* -python-markdown-math==0.8 -mkdocs-macros-plugin==1.* +zensical==0.0.* +# Custom Pygments fork adds the `soar` lexer used in fenced code blocks. pygments @ git+https://github.com/moschmdt/pygments@feature/soar pre-commit==3.8.* From 3bca8f7b979e0f77f97e14a7d75927b48b1ce7a1 Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Tue, 8 Sep 2026 22:08:57 +0200 Subject: [PATCH 2/7] fix: double H1 suppress outline --- main.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/main.py b/main.py index f0536c32..bc5cbfb1 100644 --- a/main.py +++ b/main.py @@ -15,11 +15,16 @@ def soar_version(): @env.macro def tutorial_wip_warning(file_name): + # Emitted as an admonition rather than a heading so it does not add a + # second

to the page, which suppresses the "On this page" outline. + file_name = file_name.strip() + url = ( + "https://github.com/SoarGroup/Soar/releases/download/" + f"releases%2F{soar_version()}/{file_name}" + ) return ( - "# 🚧 Under Construction 🚧\n The HTML version of the tutorial " - "is currently under construction; in particular, the figure " - "annotations are missing. You may wish to view the PDF version " - f"[here](https://github.com/SoarGroup/Soar/releases/download/releases%2F{soar_version()}/{file_name}) " - "instead." - + '!!! warning "Under Construction"\n\n' + " The HTML version of the tutorial is currently under " + "construction; in particular, the figure annotations are missing. " + f"You may wish to view the PDF version [here]({url}) instead.\n" ) From 389ff637a6d8640ed8deedaae32cac85d79e71e8 Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Tue, 8 Sep 2026 22:34:06 +0200 Subject: [PATCH 3/7] style: text as block align --- docs/stylesheets/extra.css | 17 +++++++++++++++++ mkdocs.yml | 3 +++ 2 files changed, 20 insertions(+) create mode 100644 docs/stylesheets/extra.css diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 00000000..cfc2cd0d --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,17 @@ +/* Justify body text (block alignment) instead of the default left alignment */ +.md-typeset p, +.md-typeset li { + text-align: justify; + text-justify: inter-word; + hyphens: auto; +} + +/* Keep captions, admonition titles, and tables left-aligned */ +.md-typeset caption, +.md-typeset figcaption, +.md-typeset .admonition-title, +.md-typeset th, +.md-typeset td { + text-align: left; + hyphens: manual; +} diff --git a/mkdocs.yml b/mkdocs.yml index 98965f0e..34ea27c3 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -54,6 +54,9 @@ theme: icon: material/toggle-switch name: Switch to light mode +extra_css: + - stylesheets/extra.css + extra_javascript: - javascript/mathjax.js - https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js From 9d6df781c5449767d40d20968280629deac742b0 Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Tue, 8 Sep 2026 23:00:38 +0200 Subject: [PATCH 4/7] style: update pre-commit config and markdownlint for Zensical compatibility --- .github/workflows/check_pr.yml | 4 +- .markdownlint.json | 31 ---------- .markdownlint.jsonc | 100 +++++++++++++++++++++++++++++++++ .pre-commit-config.yaml | 11 +++- 4 files changed, 111 insertions(+), 35 deletions(-) delete mode 100644 .markdownlint.json create mode 100644 .markdownlint.jsonc diff --git a/.github/workflows/check_pr.yml b/.github/workflows/check_pr.yml index 19943f9e..c4ff70fe 100644 --- a/.github/workflows/check_pr.yml +++ b/.github/workflows/check_pr.yml @@ -23,13 +23,13 @@ jobs: files: '**/*.md' separator: "," - - uses: DavidAnson/markdownlint-cli2-action@v14 + - uses: DavidAnson/markdownlint-cli2-action@v20 continue-on-error: false if: steps.changed-files.outputs.any_changed == 'true' with: globs: ${{ steps.changed-files.outputs.all_changed_files }} separator: "," - config: '.markdownlint.json' + config: '.markdownlint.jsonc' - run: pip install -r requirements.txt - run: zensical build --clean diff --git a/.markdownlint.json b/.markdownlint.json deleted file mode 100644 index 1707e9d9..00000000 --- a/.markdownlint.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "MD007": { - "indent": 4 - }, - "MD030": { - "ul_single": 3, - "ul_multi": 3, - "ol_multi": 2, - "ol_single": 2 - }, - "MD024": { - "siblings_only": true - }, - "MD013": { - "tables": false, - "code_blocks": false - }, - "MD026": { - "punctuation": ".,;:。:" - }, - "MD025": { - "front_matter_title": "" - }, - "MD033": { - "allowed_elements": [ - "div", - "p", - "a" - ] - } -} diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 00000000..a0a7c153 --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,100 @@ +{ + // markdownlint config tuned for compatibility with the Zensical toolchain + // (https://zensical.org/studio/write/linting/). + // + // Zensical Studio ships its own Markdown auto-formatter + linter. To avoid + // fighting it we split responsibilities: + // + // * Zensical auto-formatter -> owns style (list markers, blank lines, + // fences, tables, emphasis, headings, trailing whitespace, line + // endings). Every markdownlint rule the formatter rewrites is disabled + // below so formatter output always passes `markdownlint`. + // * Zensical linter (default rules) -> owns heading/level-skip (MD001), + // link/empty-destination (MD042), image/missing-alt (MD045). Disabled + // here to avoid duplicate reports. + // * markdownlint -> keeps the content/structure checks that neither + // Zensical tool enforces by default, plus the rules that map to + // Zensical *opt-in* rules (MD025, MD033, MD040, MD041) so they stay + // enforced in CI even for contributors who don't use Studio. + + "default": true, + + // --- Owned by the Zensical auto-formatter (style) --- + "MD003": false, // heading style + "MD004": false, // unordered list marker style + "MD009": false, // trailing spaces + "MD010": false, // hard tabs + "MD012": false, // multiple consecutive blank lines + "MD018": false, // space after ATX hash + "MD019": false, // multiple spaces after ATX hash + "MD020": false, // space inside closed ATX hash + "MD021": false, // multiple spaces inside closed ATX hash + "MD022": false, // blank lines around headings + "MD023": false, // headings must start at line start + "MD027": false, // multiple spaces after blockquote symbol + "MD029": false, // ordered list item prefix + "MD030": false, // spaces after list markers + "MD031": false, // blank lines around fenced code blocks + "MD032": false, // blank lines around lists + "MD035": false, // horizontal rule style + "MD037": false, // spaces inside emphasis markers + "MD038": false, // spaces inside code span elements + "MD039": false, // spaces inside link text + "MD047": false, // single trailing newline + "MD048": false, // code fence style + "MD049": false, // emphasis style + "MD050": false, // strong style + "MD054": false, // link/image style + "MD055": false, // table pipe style + "MD058": false, // blank lines around tables + "MD060": false, // table column style + + // --- Covered by the Zensical linter's default rules --- + "MD001": false, // -> heading/level-skip + "MD042": false, // -> link/empty-destination + "MD045": false, // -> image/missing-alt + + // MD046 (code block style) is off: markdownlint has no admonition support, + // so the 4-space-indented body of `!!! note` / `???+ info` blocks is + // misread as an indented code block, making the "consistent" check + // meaningless. Zensical's code/indented rule is opt-in and left off. + "MD046": false, + + // --- Kept: content/structure checks, with project overrides --- + "MD007": { + // 4-space nested list indent is a hard requirement of Python Markdown, + // which Zensical renders with; its linter does not guard this. + "indent": 4 + }, + // MD013 (line length) is off: the Zensical auto-formatter does not wrap + // prose, so a hard column limit would fight it. Re-enable with + // { "tables": false, "code_blocks": false } if you want it back. + "MD013": false, + "MD024": { + "siblings_only": true + }, + "MD025": { + "front_matter_title": "" + }, + "MD026": { + "punctuation": ".,;:。:" + }, + "MD033": { + // Zensical's html/disallowed rule is opt-in (off), so it permits all + // of these. This list mirrors the inline HTML the docs actually use. + "allowed_elements": [ + "div", + "p", + "a", + "br", + "sup", + "sub", + "kbd", + "small", + "abbr", + "span", + "details", + "summary" + ] + } +} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0fdc9d37..3e874ac0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,11 +1,18 @@ +# markdownlint is scoped to the rules the Zensical toolchain leaves to it; +# see .markdownlint.jsonc for the rationale. repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v2.3.0 + rev: v6.0.0 hooks: - id: check-yaml - id: end-of-file-fixer + # Matches .editorconfig insert_final_newline = true (applies to *.md too). - id: trailing-whitespace + # Markdown trailing whitespace is significant (hard line breaks) and + # .editorconfig exempts *.md; leave *.md to the Zensical formatter. + exclude_types: [markdown] - repo: https://github.com/DavidAnson/markdownlint-cli2 - rev: v0.14.0 + rev: v0.23.2 hooks: - id: markdownlint-cli2 + # Auto-discovers .markdownlint.jsonc at the repo root. From 80775e4e31a5d7c19afbec3f81ad0078b8313e92 Mon Sep 17 00:00:00 2001 From: Moritz Schmidt Date: Tue, 8 Sep 2026 23:18:23 +0200 Subject: [PATCH 5/7] style: resolve linting errors --- docs/development/SoarTechnicalFAQ.md | 2 +- .../soar_data_collector.md | 4 +- .../agent_development_tools/soareditor.md | 2 +- .../ultraedit_syntax_coloring_wordfile.md | 2 +- .../agent_development_tools/visualsoar.md | 2 +- docs/downloads/domains/eaters.md | 1 - .../domains/general_game_player_translator.md | 1 - docs/downloads/domains/infinite_mario_rl.md | 1 - docs/downloads/domains/pddl_translator.md | 1 - docs/downloads/domains/roomsworld.md | 1 - docs/downloads/domains/soartext-io.md | 1 - docs/downloads/domains/tanksoar.md | 1 - docs/downloads/domains/taxi.md | 1 - docs/downloads/domains/wordnet_wsd.md | 1 - .../domains/wordnet_wsd_(with_parse_trees).md | 1 - docs/downloads/soar/archive.md | 4 +- docs/downloads/soar/jsoar.md | 2 +- docs/home/CommercialSoarOrganizations.md | 5 +- docs/home/QuickStart.md | 4 +- docs/home/ResearchGroups.md | 11 +- docs/javascript/mathjax.js | 5 +- docs/reference/cli/names.py | 4 +- docs/reference/index.md | 2 +- docs/soar_manual/01_Introduction.md | 2 +- docs/soar_manual/02_TheSoarArchitecture.md | 1930 +++++++++-------- .../04_ProceduralKnowledgeLearning.md | 624 +++--- docs/soar_manual/Images/rl-optrace.fig | 2 +- docs/soar_manual/Images/smem-concept.svg | 2 +- docs/soar_manual/blocksworld.md | 2 +- docs/tutorials/IntroSoarDebugger/index.md | 8 +- docs/tutorials/SMLQuickStartGuide.md | 4 +- docs/tutorials/soar_tutorial/01.md | 190 +- docs/tutorials/soar_tutorial/02.md | 459 ++-- docs/tutorials/soar_tutorial/03.md | 458 ++-- docs/tutorials/soar_tutorial/04.md | 126 +- docs/tutorials/soar_tutorial/05.md | 177 +- docs/tutorials/soar_tutorial/06.md | 113 +- docs/tutorials/soar_tutorial/07.md | 50 +- docs/tutorials/soar_tutorial/08.md | 56 +- .../soar_tutorial/TankEatersConfigFile.md | 57 +- docs/tutorials/soar_tutorial/index.md | 18 +- docs/workshops/20/index.md | 2 +- docs/workshops/20/index_original.html | 11 - docs/workshops/21.md | 4 +- docs/workshops/24/24_announcement.html | 118 +- docs/workshops/24/index.md | 151 +- docs/workshops/24/register24.html | 40 +- docs/workshops/25/25_announcement.html | 96 +- docs/workshops/25/index.md | 141 +- docs/workshops/25/register25.html | 34 +- docs/workshops/26/register26.html | 38 +- docs/workshops/29.md | 4 +- docs/workshops/31.md | 143 +- docs/workshops/33.md | 18 +- docs/workshops/34.md | 22 +- docs/workshops/39.md | 16 +- includes/abbreviations.md | 1 + 57 files changed, 2652 insertions(+), 2524 deletions(-) diff --git a/docs/development/SoarTechnicalFAQ.md b/docs/development/SoarTechnicalFAQ.md index 9f52a28c..8e880b13 100644 --- a/docs/development/SoarTechnicalFAQ.md +++ b/docs/development/SoarTechnicalFAQ.md @@ -283,7 +283,7 @@ is a good model to follow. If you're working on a command line application without a GUI, then the _TestCommandLine_ application is a good reference as it demonstrates how to support interruption in a single-threaded application. -A detailed explanation about threads in Soar is provided [here](../development/soar/ThreadsInSML.md). +A detailed explanation about threads in Soar is provided in [Threads in SML](../development/soar/ThreadsInSML.md). ## How do I properly manage memory in my SML application? diff --git a/docs/downloads/agent_development_tools/soar_data_collector.md b/docs/downloads/agent_development_tools/soar_data_collector.md index 36e43a43..103078df 100644 --- a/docs/downloads/agent_development_tools/soar_data_collector.md +++ b/docs/downloads/agent_development_tools/soar_data_collector.md @@ -25,8 +25,8 @@ Statistics are collected at configurable intervals during a run and include: No pre-built binaries are currently available for this project. -* The project repository is [here](https://github.com/voigtjr/soar-datacollector) -* A JSoar version is also available [here](https://github.com/voigtjr/jsoar-datacollector) +* The [project repository](https://github.com/voigtjr/soar-datacollector) is on GitHub +* A [JSoar version](https://github.com/voigtjr/jsoar-datacollector) is also available ## Documentation diff --git a/docs/downloads/agent_development_tools/soareditor.md b/docs/downloads/agent_development_tools/soareditor.md index e95899bd..d61b60f3 100644 --- a/docs/downloads/agent_development_tools/soareditor.md +++ b/docs/downloads/agent_development_tools/soareditor.md @@ -31,7 +31,7 @@ the plugin. ## Documentation -While there isn't much documentation yet, you can find a page on the basics [here](https://github.com/SoarGroup/Soar-Editor/wiki/Using-the-Soar-Editor). +While there isn't much documentation yet, you can find a [page on the basics](https://github.com/SoarGroup/Soar-Editor/wiki/Using-the-Soar-Editor). ## Developers diff --git a/docs/downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md b/docs/downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md index 9f0cec26..efcb0633 100644 --- a/docs/downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md +++ b/docs/downloads/agent_development_tools/ultraedit_syntax_coloring_wordfile.md @@ -25,7 +25,7 @@ of its contents except the first line) * Version 15.00 and later: Download and save it into your "wordfile" directory which by default is `%appdata%\IDMComp\UltraEdit\wordfiles`, unless you have -specified a different directory. Further help and documentation is available [here](http://www.ultraedit.com/support/tutorials_power_tips/ultraedit/add_a_wordfile.html). +specified a different directory. Further [help and documentation on adding a wordfile](http://www.ultraedit.com/support/tutorials_power_tips/ultraedit/add_a_wordfile.html) is available. * Version 14.20 and previous: Visit [this page](http://www.ultraedit.com/support/tutorials_power_tips/ultraedit/add_a_wordfile_pre_v15.html) for instructions. diff --git a/docs/downloads/agent_development_tools/visualsoar.md b/docs/downloads/agent_development_tools/visualsoar.md index 25204f11..2bcc96dd 100644 --- a/docs/downloads/agent_development_tools/visualsoar.md +++ b/docs/downloads/agent_development_tools/visualsoar.md @@ -21,7 +21,7 @@ it VisualSoar. ## Documentation In addition to the manual included with the SoarSuite release, the keyboard and -mouse controls are documented [here](https://soar.eecs.umich.edu/reference/VisualSoarKeyboardAndMouseControls/). +mouse controls are documented in the [VisualSoar keyboard and mouse controls reference](https://soar.eecs.umich.edu/reference/VisualSoarKeyboardAndMouseControls/). ## Developers diff --git a/docs/downloads/domains/eaters.md b/docs/downloads/domains/eaters.md index d916ca99..cf350467 100644 --- a/docs/downloads/domains/eaters.md +++ b/docs/downloads/domains/eaters.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/general_game_player_translator.md b/docs/downloads/domains/general_game_player_translator.md index 0beff6bf..ffc36326 100644 --- a/docs/downloads/domains/general_game_player_translator.md +++ b/docs/downloads/domains/general_game_player_translator.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/infinite_mario_rl.md b/docs/downloads/domains/infinite_mario_rl.md index e61bbb41..ec8edb86 100644 --- a/docs/downloads/domains/infinite_mario_rl.md +++ b/docs/downloads/domains/infinite_mario_rl.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/pddl_translator.md b/docs/downloads/domains/pddl_translator.md index e00addf9..8adb193f 100644 --- a/docs/downloads/domains/pddl_translator.md +++ b/docs/downloads/domains/pddl_translator.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/roomsworld.md b/docs/downloads/domains/roomsworld.md index c0d3eb02..18b0a7a0 100644 --- a/docs/downloads/domains/roomsworld.md +++ b/docs/downloads/domains/roomsworld.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/soartext-io.md b/docs/downloads/domains/soartext-io.md index 6ae6af8d..9d9f2af6 100644 --- a/docs/downloads/domains/soartext-io.md +++ b/docs/downloads/domains/soartext-io.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/tanksoar.md b/docs/downloads/domains/tanksoar.md index c0a0bc1e..1571a712 100644 --- a/docs/downloads/domains/tanksoar.md +++ b/docs/downloads/domains/tanksoar.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/taxi.md b/docs/downloads/domains/taxi.md index 7ae58533..3e1ef2de 100644 --- a/docs/downloads/domains/taxi.md +++ b/docs/downloads/domains/taxi.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/wordnet_wsd.md b/docs/downloads/domains/wordnet_wsd.md index 039fe0ae..c0074827 100644 --- a/docs/downloads/domains/wordnet_wsd.md +++ b/docs/downloads/domains/wordnet_wsd.md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/domains/wordnet_wsd_(with_parse_trees).md b/docs/downloads/domains/wordnet_wsd_(with_parse_trees).md index 698e4ad0..3e889066 100644 --- a/docs/downloads/domains/wordnet_wsd_(with_parse_trees).md +++ b/docs/downloads/domains/wordnet_wsd_(with_parse_trees).md @@ -57,4 +57,3 @@ TODO ## Language TODO (not for agents) - diff --git a/docs/downloads/soar/archive.md b/docs/downloads/soar/archive.md index fbc16359..866a0bbf 100644 --- a/docs/downloads/soar/archive.md +++ b/docs/downloads/soar/archive.md @@ -2,8 +2,8 @@ ## Soar 9 -Releases of Soar 9.6.1 and later are available from the releases page on the -Soar GitHub repository [here](https://github.com/SoarGroup/Soar/releases). +Releases of Soar 9.6.1 and later are available from the +[Soar GitHub releases page](https://github.com/SoarGroup/Soar/releases). ### Soar 9.6.0 diff --git a/docs/downloads/soar/jsoar.md b/docs/downloads/soar/jsoar.md index 414723cc..e49bb5ca 100644 --- a/docs/downloads/soar/jsoar.md +++ b/docs/downloads/soar/jsoar.md @@ -15,7 +15,7 @@ Scala, Clojure, etc) ## Download -JSoar is downloadable from GitHub [here](https://soartech.github.io/jsoar/). +JSoar is [downloadable from the jsoar site](https://soartech.github.io/jsoar/). ## Documentation diff --git a/docs/home/CommercialSoarOrganizations.md b/docs/home/CommercialSoarOrganizations.md index 4608132b..22727b1a 100644 --- a/docs/home/CommercialSoarOrganizations.md +++ b/docs/home/CommercialSoarOrganizations.md @@ -4,11 +4,12 @@ tags: --- + # Commercial Organizations Using Soar -## Soar Technology, Inc. +## Soar Technology Inc [Soar Technology Inc.](http://www.soartech.com/) is utilizing advanced artificial intelligence, grounded in scientific principles of human-system @@ -18,7 +19,7 @@ command and control, information visualization, robotics, and intelligence analysis, for the U.S. Army, Navy, Air Force, DARPA, JFCOM, DMSO and the intelligence community. -## Cogniteam, Ltd. +## Cogniteam [Cogniteam](http://www.cogniteam.com/) is an Israeli company offering project development, consulting, and professional services in AI and robotics in diff --git a/docs/home/QuickStart.md b/docs/home/QuickStart.md index 428e5890..8aaaabc0 100644 --- a/docs/home/QuickStart.md +++ b/docs/home/QuickStart.md @@ -8,8 +8,8 @@ Soar, such as the debugger and VisualSoar, you will need [Java version 11](https://adoptium.net/temurin/releases/?variant=openjdk11) or higher installed. -1. Download Soar Release archive -[here](https://github.com/SoarGroup/Soar/releases/download/releases%2F{{soar_version}}/SoarSuite_{{soar_version}}-Multiplatform.zip) +1. Download the +[Soar Release archive](https://github.com/SoarGroup/Soar/releases/download/releases%2F{{soar_version}}/SoarSuite_{{soar_version}}-Multiplatform.zip) and extract to the location of your choice. 2. Run the Soar debugger via one of the scripts included in this folder: diff --git a/docs/home/ResearchGroups.md b/docs/home/ResearchGroups.md index a63e4620..93eaba8c 100644 --- a/docs/home/ResearchGroups.md +++ b/docs/home/ResearchGroups.md @@ -4,6 +4,7 @@ tags: --- + # Soar Research Groups @@ -11,15 +12,15 @@ tags: There are many institutions conducting Soar research all over the world. In the following subsections, you can find links to some of them: -- [University of Michigan Soar Group](http://soar.eecs.umich.edu/UofMSoarGroup) +- [University of Michigan Soar Group](http://soar.eecs.umich.edu/UofMSoarGroup) A full listing of all members of the University of Michigan Soar group and Alumnae -- [Other Academic Institutions](./OtherAcademicInstitutions.md) +- [Other Academic Institutions](./OtherAcademicInstitutions.md) A listing of various research groups around the world who use Soar in their work. -- [Commercial Soar Organizations](./CommercialSoarOrganizations.md) +- [Commercial Soar Organizations](./CommercialSoarOrganizations.md) A listing of companies that use Soar in commercial applications or consulting work. Soar researchers keep in touch via the soar-group email mailing lists, which you can join on this page. If you would like to have a link to your research group or company listed on -these pages, please send a brief summary and the URL to [John Laird] -(mailto:laird@umich.edu) with the subject "Soar Research Group". +these pages, please send a brief summary and the URL to +[John Laird](mailto:laird@umich.edu) with the subject "Soar Research Group". diff --git a/docs/javascript/mathjax.js b/docs/javascript/mathjax.js index 1c35fc15..85528390 100644 --- a/docs/javascript/mathjax.js +++ b/docs/javascript/mathjax.js @@ -10,8 +10,7 @@ window.MathJax = { processHtmlClass: "arithmatex" } }; - - document$.subscribe(() => { + + document$.subscribe(() => { MathJax.typesetPromise() }) - \ No newline at end of file diff --git a/docs/reference/cli/names.py b/docs/reference/cli/names.py index afbb8578..ebd6bbbe 100644 --- a/docs/reference/cli/names.py +++ b/docs/reference/cli/names.py @@ -1,4 +1,4 @@ -import os +import os # Run this file to generate the filenames and links for the mkdocs.yml navigation bar. @@ -11,4 +11,4 @@ cmd_name = os.path.splitext(filename)[0][4:] # Remove 'cmd_' prefix cmd_name = os.path.splitext(filename)[0][4:] # Remove 'cmd_' prefix line_of_code = f'- {cmd_name}: "reference/cli/{filename}"' - print(line_of_code) \ No newline at end of file + print(line_of_code) diff --git a/docs/reference/index.md b/docs/reference/index.md index 4a938e09..cf5aa074 100644 --- a/docs/reference/index.md +++ b/docs/reference/index.md @@ -1 +1 @@ -# Reference \ No newline at end of file +# Reference diff --git a/docs/soar_manual/01_Introduction.md b/docs/soar_manual/01_Introduction.md index 69b01847..0447125e 100644 --- a/docs/soar_manual/01_Introduction.md +++ b/docs/soar_manual/01_Introduction.md @@ -120,7 +120,7 @@ To avoid redundant entries, please search for duplicate issues first. Mailing Address: -``` +```text The Soar Group Artificial Intelligence Laboratory University of Michigan diff --git a/docs/soar_manual/02_TheSoarArchitecture.md b/docs/soar_manual/02_TheSoarArchitecture.md index c29b309b..1bb53f2a 100644 --- a/docs/soar_manual/02_TheSoarArchitecture.md +++ b/docs/soar_manual/02_TheSoarArchitecture.md @@ -1,70 +1,78 @@ # 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 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). +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. +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. +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.](Images/select-apply.svg) + /// caption 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. +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* +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. + 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 @@ -72,60 +80,65 @@ 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: +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 +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](#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 with A on top, B in the middle, and C on the bottom. -The initial state and the goal are illustrated in Figure 2.2. +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 with A on +top, B in the middle, and C on the bottom. The initial state and the goal are +illustrated in the next figure. The Soar code for this task is available for download here and can be [viewed in the manual here](blocksworld.md#blocksworld-soar-rules). You do not need to look at the code at this point. -![The initial state and goal of the "blocks-world" task.](Images/blocks.svg) +![The initial state and goal of the "blocks-world" task.](Images/blocks.svg) + /// caption 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 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) @@ -136,23 +149,38 @@ 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. +The initial state in our blocks-world task - before any operators have been +proposed or selected - is illustrated in the following figure. + +![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.](Images/ab-wmem.svg) + +/// caption +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. +/// 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 +The next figure illustrates working memory after the first operator has been selected. There are six operators proposed, and only one of these is actually selected. +![An abstract illustration of working memory in the blocks world after the first operator has been selected.](Images/ab-wmem2.svg) + +/// caption +An abstract illustration of working memory in the blocks world after the first +operator has been 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 +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. @@ -164,22 +192,10 @@ 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.](Images/ab-wmem.svg) -/// caption -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.](Images/ab-wmem2.svg) -/// caption -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 +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 @@ -196,10 +212,11 @@ candidate operators. For example, a preference may say that operator A is a 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](#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.](Images/blocks-proposal.svg) + /// caption -The six operators proposed for the initial state of the blocks world each move one block to a new location. +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 @@ -209,37 +226,41 @@ 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. +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](#impasses-and-substates). +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 texts created. +Impasses are discussed in [Impasses and Substates](#impasses-and-substates). -In our blocks-world example, the second case holds, and Soar can select one of the operators -randomly +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). +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 @@ -251,187 +272,221 @@ 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). +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](#footnote1) +4. The place that the block is moving to is no longer clear — unless it is the + table, which is always considered "clear". + +!!! note + + In this blocks-world task, the table always has room for another block, so it + is represented as always being "clear". -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. +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. +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". +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 +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 +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 ![The problem space in the blocks-world includes all operators that move blocks from one location to another and all possible configurations of the three blocks.](Images/blocks-ps.svg) + /// caption -The problem space in the blocks-world includes all operators that move blocks from one location to another and all possible configurations of the three blocks. +The problem space in the blocks-world includes all operators that move blocks +from one location to another and all possible configurations of the three +blocks. /// -Soar solves a problem in this problem space, it does not explicitly generate all of the states, -examine them, and then create a path. Instead, Soar isin a specific state at a given time -(represented in working memory), attempting to select an operator that will move it to a -new state. It uses whatever knowledge it has about selecting operators given the current -situation, and if its knowledge is sufficient, it will move toward its goal. - -The same problem could be recast in Soar as a planning problem, where the goal is to develop -a plan to solve the problem, instead of just solving the problem. In that case, a state in Soar -would consist of a plan, which in turn would have representations of blocks-world states and -operators from the original space. The operators would perform editing operations on the -plan, such as adding new blocks-world operators, simulating those operators, etc. In both -formulations of the problem, Soar is still applying operators to generate new states, it is just +Soar solves a problem in this problem space, it does not explicitly generate all +of the states, examine them, and then create a path. Instead, Soar isin a +specific state at a given time (represented in working memory), attempting to +select an operator that will move it to a new state. It uses whatever knowledge +it has about selecting operators given the current situation, and if its +knowledge is sufficient, it will move toward its goal. + +The same problem could be recast in Soar as a planning problem, where the goal +is to develop a plan to solve the problem, instead of just solving the problem. +In that case, a state in Soar would consist of a plan, which in turn would have +representations of blocks-world states and operators from the original space. +The operators would perform editing operations on the plan, such as adding new +blocks-world operators, simulating those operators, etc. In both formulations of +the problem, Soar is still applying operators to generate new states, it is just that the states and operators have different content. -The remaining sections in this chapter describe the memories and processes of Soar: work- -ing memory, production memory, preference memory, Soar’s execution cycle (the decision -procedure), learning, and how input and output fit in. +The remaining sections in this chapter describe the memories and processes of +Soar: work- ing memory, production memory, preference memory, Soar’s execution +cycle (the decision procedure), learning, and how input and output fit in. ## Working memory: The Current Situation -Soar represents the current problem-solving situation in its working memory. Thus, working -memory holds the current state and operator and is Soar’s "short-term" knowledge, reflecting -the current knowledge of the world and the status in problem solving. - -Working memory contains elements called working memory elements, or WMEs for short. -Each WME contains a very specific piece of information; for example, a WME might say -that "B1 is a block". Several WMEs collectively may provide more information about the -same object, for example, "B1 is a block", "B1 is named A", "B1 is on the table", etc. These -WMEs are related because they are all contributing to the description of something that -is internally known to Soar as "B1". B1 is called an ***identifier***; the group of WMEs that -share this identifier are referred to as an object in working memory. Each WME describes a -different ***attribute*** of the object, for example, its name or type or location; each attribute -has a ***value*** associated with it, for example, the name is A, the type is block, and the -position is on the table. Therefore, each WME is an identifier-attribute-value triple, and all -WMEs with the same identifier are part of the same object. - -Objects in working memory are *linked* to other objects: The value of one WME may be an -identifier of another object. For example, a WME might say that "B1 is on top of T1", and -another collection of WMEs might describe the object T1: "T1 is a table", "T1 is brown", -and "T1 is on top of F1". And still another collection of WMEs might describe the object -F1: "F1 is a floor", etc. All objects in working memory must be linked to a state, either -directly or indirectly (through other objects). Objects that are not linked to a state will be -automatically removed from working memory by the Soar architecture. - -WMEs are also often called *augmentations* because they "augment" the object, +Soar represents the current problem-solving situation in its working memory. +Thus, working memory holds the current state and operator and is Soar’s +"short-term" knowledge, reflecting the current knowledge of the world and the +status in problem solving. + +Working memory contains elements called working memory elements, or WMEs for +short. Each WME contains a very specific piece of information; for example, a +WME might say that "B1 is a block". Several WMEs collectively may provide more +information about the same object, for example, "B1 is a block", "B1 is named +A", "B1 is on the table", etc. These WMEs are related because they are all +contributing to the description of something that is internally known to Soar as +"B1". B1 is called an **identifier**; the group of WMEs that share this +identifier are referred to as an object in working memory. Each WME describes a +different **attribute** of the object, for example, its name or type or +location; each attribute has a **value** associated with it, for example, the +name is A, the type is block, and the position is on the table. Therefore, each +WME is an identifier-attribute-value triple, and all WMEs with the same +identifier are part of the same object. + +Objects in working memory are _linked_ to other objects: The value of one WME +may be an identifier of another object. For example, a WME might say that "B1 is +on top of T1", and another collection of WMEs might describe the object T1: "T1 +is a table", "T1 is brown", and "T1 is on top of F1". And still another +collection of WMEs might describe the object F1: "F1 is a floor", etc. All +objects in working memory must be linked to a state, either directly or +indirectly (through other objects). Objects that are not linked to a state will +be automatically removed from working memory by the Soar architecture. + +WMEs are also often called _augmentations_ because they "augment" the object, providing more detail about it. While these two terms are somewhat redundant, WME is a term that is used more often to refer to the contents of working memory -(as a single *identifier-attribute-value* triple), while augmentation is a term +(as a single _identifier-attribute-value_ triple), while augmentation is a term that is used more often to refer to the description of an object. Working memory is illustrated at an abstract level in Figure 2.3. -The attribute of an augmentation is usually a constant, such as `name` or `type`, because -in a sense, the attribute is just a label used to distinguish one link in working memory from -another.[2](#footnote2) - -The value of an augmentation may be either a constant, such as `red`, or an identifier, such -as 06. When the value is an identifier, it refers to an object in working memory that may -have additional substructure. In semantic net terms, if a value is a constant, then it is a -terminal node with no links; if it is an identifier it is a non terminal node. - -One key concept of Soar is that working memory is a set, which means that there can never -be two elements in working memory at the same time that have the same identifier-attribute- -value triple (this is prevented by the architecture). However, it is possible to have multiple -working memory elements that have the same identifier and attribute, but that each have -different values. When this happens, we say the attribute is a *multi-valued attribute*, which -is often shortened to be *multi-attribute*. - -An object is defined by its augmentations and not by its identifier. An identifier is simply a -label or pointer to the object. On subsequent runs of the same Soar program, there may be -an object with exactly the same augmentations, but a different identifier, and the program -will still reason about the object appropriately. Identifiers are internal markers for Soar; -they can appear in working memory, but they never appear in a production. - -There is no predefined relationship between objects in working memory and "real objects" -in the outside world. Objects in working memory may refer to real objects, such as block -A; features of an object, such as the color red or shape cube; a relation between objects, -such as on top; classes of objects, such as blocks; etc. The actual names of attributes and -values have no meaning to the Soar architecture (aside from a few WMEs created by the -architecture itself). For example, Soar doesn’t care whether the things in the blocks world -are called "blocks" or "cubes" or "chandeliers". It is up to the Soar programmer to pick +The attribute of an augmentation is usually a constant, such as `name` or +`type`, because in a sense, the attribute is just a label used to distinguish +one link in working memory from another. + +!!! note + + In order to allow these links to have some substructure, the attribute name + may be an identifier, which means that the attribute may itself have + attributes and values, as specified by additional working memory elements. + +The value of an augmentation may be either a constant, such as `red`, or an +identifier, such as 06. When the value is an identifier, it refers to an object +in working memory that may have additional substructure. In semantic net terms, +if a value is a constant, then it is a terminal node with no links; if it is an +identifier it is a non terminal node. + +One key concept of Soar is that working memory is a set, which means that there +can never be two elements in working memory at the same time that have the same +identifier-attribute- value triple (this is prevented by the architecture). +However, it is possible to have multiple working memory elements that have the +same identifier and attribute, but that each have different values. When this +happens, we say the attribute is a _multi-valued attribute_, which is often +shortened to be _multi-attribute_. + +An object is defined by its augmentations and not by its identifier. An +identifier is simply a label or pointer to the object. On subsequent runs of the +same Soar program, there may be an object with exactly the same augmentations, +but a different identifier, and the program will still reason about the object +appropriately. Identifiers are internal markers for Soar; they can appear in +working memory, but they never appear in a production. + +There is no predefined relationship between objects in working memory and "real +objects" in the outside world. Objects in working memory may refer to real +objects, such as block A; features of an object, such as the color red or shape +cube; a relation between objects, such as on top; classes of objects, such as +blocks; etc. The actual names of attributes and values have no meaning to the +Soar architecture (aside from a few WMEs created by the architecture itself). +For example, Soar doesn’t care whether the things in the blocks world are called +"blocks" or "cubes" or "chandeliers". It is up to the Soar programmer to pick suitable labels and to use them consistently. The elements in working memory arise from one of four sources: -1. ***Productions***: The actions on the RHS of productions create most working memory - elements. -2. ***Architecture***: - - (a) State augmentations: The decision procedure automatically creates some special - state augmentations (type, superstate, impasse, ...) whenever a state is created. - States are created during initialization (the first state) or because of an impasse - (a substate). - - (b) Operator augmentations: The decision procedure creates the operator - augmentation of the state based on preferences. This records the selection of - the current operator. -3. ***Memory Systems*** -4. ***SVS*** -5. ***The Environment***: External I/O systems create working memory elements on the - input-link for sensory data. +1. **Productions**: The actions on the RHS of productions create most working memory + elements. +2. **Architecture**: + - (a) State augmentations: The decision procedure automatically creates some + special state augmentations (type, superstate, impasse, ...) whenever a + state is created. States are created during initialization (the first + state) or because of an impasse (a substate). + - (b) Operator augmentations: The decision procedure creates the operator + augmentation of the state based on preferences. This records the selection + of the current operator. +3. **Memory Systems** +4. **SVS** +5. **The Environment**: External I/O systems create working memory elements on + the input-link for sensory data. The elements in working memory are removed in six different ways: -1. The decision procedure automatically removes all state augmentations it creates when - the impasse that led to their creation is resolved. -2. The decision procedure removes the operator augmentation of the state when that - operator is no longer selected as the current operator. -3. Production actions that user `reject` preferences remove working memory elements that - were created by other productions. -4. The architecture automatically removes i-supported WMEs when the productions that - created them no longer match. -5. The I/O system removes sensory data from the input-link when it is no longer valid. -6. The architecture automatically removes WMEs that are no longer linked to a state - (because some other WME has been removed). - -For the most part, the user is free to use any attributes and values that are appropriate for the -task. However, states have special augmentations that cannot be directly created, removed, -or modified by rules. These include the augmentations created when a state is created, and -the state’s operator augmentation that signifies the current operator (and is created based -on preferences). The specific attributes that the Soar architecture automatically creates are -listed in [Impasses in Working Memory and in Production](./03_SyntaxOfSoarPrograms.md#impasses-in-working-memory-and-in-productions). Productions may create any other attributes for states. - -Preferences are held in a separate *preference memory* where they cannot be tested -by productions. There is one notable exception. Since a soar program may need to -reason about candidate operators,acceptable preferences are made available in -working memory as well. The `acceptable` preferences can then be tested by -productions, which allows a Soar program to reason about candidates operators to -determine which one should be selected. Preference memory and the different -types of preferences will be discussed in Section [Preference Memory: Selection Knowledge](02_TheSoarArchitecture.md#preference-memory-selection-knowledge). +1. The decision procedure automatically removes all state augmentations it + creates when the impasse that led to their creation is resolved. +2. The decision procedure removes the operator augmentation of the state when + that operator is no longer selected as the current operator. +3. Production actions that user `reject` preferences remove working memory + elements that were created by other productions. +4. The architecture automatically removes i-supported WMEs when the productions + that created them no longer match. +5. The I/O system removes sensory data from the input-link when it is no longer + valid. +6. The architecture automatically removes WMEs that are no longer linked to a + state (because some other WME has been removed). + +For the most part, the user is free to use any attributes and values that are +appropriate for the task. However, states have special augmentations that cannot +be directly created, removed, or modified by rules. These include the +augmentations created when a state is created, and the state’s operator +augmentation that signifies the current operator (and is created based on +preferences). The specific attributes that the Soar architecture automatically +creates are listed in [Impasses in Working Memory and in +Production](./03_SyntaxOfSoarPrograms.md#impasses-in-working-memory-and-in-productions). +Productions may create any other attributes for states. + +Preferences are held in a separate _preference memory_ where they cannot be +tested by productions. There is one notable exception. Since a soar program may +need to reason about candidate operators,acceptable preferences are made +available in working memory as well. The `acceptable` preferences can then be +tested by productions, which allows a Soar program to reason about candidates +operators to determine which one should be selected. Preference memory and the +different types of preferences will be discussed in Section [Preference Memory: +Selection +Knowledge](02_TheSoarArchitecture.md#preference-memory-selection-knowledge). ## Production Memory: Long-term Procedural Knowledge -Soar represents long-term procedural knowledge as **productions** that are stored in -*production memory*, illustrated in Figure 2.7. Each production has a set of -conditions and a set of actions. If the conditions of a production match working -memory, the production *fires*, and the actions are performed. +Soar represents long-term procedural knowledge as **productions** that are +stored in _production memory_, illustrated in Figure 2.7. Each production has a +set of conditions and a set of actions. If the conditions of a production match +working memory, the production _fires_, and the actions are performed. ![An abstract view of production memory. The productions are not related to one another.](Images/ab-prodmem.svg) + /// caption An abstract view of production memory. The productions are not related to one another. /// @@ -441,54 +496,58 @@ An abstract view of production memory. The productions are not related to one an In the simplest form of a production, conditions and actions refer directly to the presence (or absence) of objects in working memory. For example, a production might say: -``` +``` txt CONDITIONS: block A is clear block B is clear ACTIONS: suggest an operator to move block A ontop of block B ``` -This is not the literal syntax of productions, but a simplification. The actual syntax is -presented in [Chapter 3](./03_SyntaxOfSoarPrograms.md). +This is not the literal syntax of productions, but a simplification. The actual +syntax is presented in [Chapter 3](./03_SyntaxOfSoarPrograms.md). -The conditions of a production may also specify the *absence* of patterns in working memory. -For example, the conditions could also specify that "block A is not red" or "there are no red -blocks on the table". But since these are not needed for our example production, there are -no examples of negated conditions for now. +The conditions of a production may also specify the _absence_ of patterns in +working memory. For example, the conditions could also specify that "block A is +not red" or "there are no red blocks on the table". But since these are not +needed for our example production, there are no examples of negated conditions +for now. -The order of the conditions of a production do not matter to Soar except that the first -condition must directly test the state. Internally, Soar will reorder the conditions so that the -matching process can be more efficient. This is a mechanical detail that need not concern -most users. However, you may print your productions to the screen or save them in a file; if -they are not in the order that you expected them to be, it is likely that the conditions have -been reordered by Soar. +The order of the conditions of a production do not matter to Soar except that +the first condition must directly test the state. Internally, Soar will reorder +the conditions so that the matching process can be more efficient. This is a +mechanical detail that need not concern most users. However, you may print your +productions to the screen or save them in a file; if they are not in the order +that you expected them to be, it is likely that the conditions have been +reordered by Soar. #### Variables in productions and multiple instantiations -In the example production above, the names of the blocks are "hardcoded", that is, they are -named specifically. In Soar productions, variables are used so that a production can apply -to a wider range of situations. - -When variables are bound to specific symbols in working memory elements by Soar’s match- -ing process, Soar creates an *instantiation* of the production. This instantiation consists of -the matched production along with a specific and consistent set of symbols that matched -the variables. A production instantiation is consistent only if every occurrence of a variable -is bound to the same value. Multiple instantiations of the same production can be created -since the same production may match multiple times, each with different variable bindings. -If blocks A and B are clear, the first production (without variables) will suggest one operator. -However, consider a new proposal production that used variables to test the names of the -block. Such a production will be instantiated twice and therefore suggest two operators: one -operator to move block A on top of block B and a second operator to move block B on top of -block A. - -Because the identifiers of objects are determined at runtime, literal identifiers cannot appear -in productions. Since identifiers occur in every working memory element, variables must be -used to test for identifiers, and using the same variables across multiple occurrences is what -links conditions together. - -Just as the elements of working memory must be linked to a state in working memory, so -must the objects referred to in a production’s conditions. That is, one condition must test -a state object *and* all other conditions must test that same state or objects that are linked -to that state. +In the example production above, the names of the blocks are "hardcoded", that +is, they are named specifically. In Soar productions, variables are used so that +a production can apply to a wider range of situations. + +When variables are bound to specific symbols in working memory elements by +Soar’s match- ing process, Soar creates an _instantiation_ of the production. +This instantiation consists of the matched production along with a specific and +consistent set of symbols that matched the variables. A production instantiation +is consistent only if every occurrence of a variable is bound to the same value. +Multiple instantiations of the same production can be created since the same +production may match multiple times, each with different variable bindings. If +blocks A and B are clear, the first production (without variables) will suggest +one operator. However, consider a new proposal production that used variables +to test the names of the block. Such a production will be instantiated twice and +therefore suggest two operators: one operator to move block A on top of block B +and a second operator to move block B on top of block A. + +Because the identifiers of objects are determined at runtime, literal +identifiers cannot appear in productions. Since identifiers occur in every +working memory element, variables must be used to test for identifiers, and +using the same variables across multiple occurrences is what links conditions +together. + +Just as the elements of working memory must be linked to a state in working +memory, so must the objects referred to in a production’s conditions. That is, +one condition must test a state object _and_ all other conditions must test that +same state or objects that are linked to that state. ### Architectural roles of productions @@ -496,9 +555,9 @@ Soar productions can fulfill the following four roles, by retrieving [different types of procedural knowledge](#types-of-procedural-knowledge-in-soar): 1. Operator proposal -1. Operator comparison -1. Operator application -1. State elaboration +2. Operator comparison +3. Operator application +4. State elaboration A single production should not fulfill more than one of these roles (except for proposing an operator and creating an absolute preference for it). Although @@ -509,32 +568,36 @@ state. ### Production Actions and Persistence -Generally, actions of a production either create preferences for operator selection, or cre- -ate/remove working memory elements. For operator proposal and comparison, a production -creates preferences for operator selection. These preferences should persist only as long as -the production instantiation that created them continues to match. When the production -instantiation no longer matches, the situation has changed, making the preference no longer -relevant. Soar automatically removes the preferences in such cases. These preferences are -said to have *i-support* (for "instantiation support"). Similarly, state elaborations are simple -inferences that are valid only so long as the production matches. Working memory elements -created as state elaborations also have i-support and remain in working memory only as -long as the production instantiation that created them continues to match working memory. -For example, the set of relevant operators changes as the state changes, thus the proposal -of operators is done with i-supported preferences. This way, the operator proposals will be -retracted when they no longer apply to the current situation. - -However, the actions of productions that *apply* an operator, either by adding or removing -elements from working memory, persist regardless of whether the operator is still selected or -the operator application production instantiation still matches. For example, in placing a -block on another block, a condition is that the second block be clear. However, the action of -placing the first block removes the fact that the second block is clear, so the condition will -no longer be satisfied. - -Thus, operator application productions do not retract their actions, even if they no longer -match working memory. This is called *o-support* (for "operator support"). Working memory -elements that participate in the application of operators are maintained throughout the -existence of the state in which the operator is applied, unless explicitly removed (or if they -become unlinked). Working memory elements are removed by a *reject* action of a operator- +Generally, actions of a production either create preferences for operator +selection, or cre- ate/remove working memory elements. For operator proposal and +comparison, a production creates preferences for operator selection. These +preferences should persist only as long as the production instantiation that +created them continues to match. When the production instantiation no longer +matches, the situation has changed, making the preference no longer relevant. +Soar automatically removes the preferences in such cases. These preferences are +said to have _i-support_ (for "instantiation support"). Similarly, state +elaborations are simple inferences that are valid only so long as the production +matches. Working memory elements created as state elaborations also have +i-support and remain in working memory only as long as the production +instantiation that created them continues to match working memory. For example, +the set of relevant operators changes as the state changes, thus the proposal of +operators is done with i-supported preferences. This way, the operator proposals +will be retracted when they no longer apply to the current situation. + +However, the actions of productions that _apply_ an operator, either by adding +or removing elements from working memory, persist regardless of whether the +operator is still selected or the operator application production instantiation +still matches. For example, in placing a block on another block, a condition is +that the second block be clear. However, the action of placing the first block +removes the fact that the second block is clear, so the condition will no longer +be satisfied. + +Thus, operator application productions do not retract their actions, even if +they no longer match working memory. This is called _o-support_ (for "operator +support"). Working memory elements that participate in the application of +operators are maintained throughout the existence of the state in which the +operator is applied, unless explicitly removed (or if they become unlinked). +Working memory elements are removed by a _reject_ action of a operator- application rule. Whether a working memory element receives o-support or i-support is determined @@ -542,227 +605,244 @@ by the structure of the production instantiation that creates the working memory element. O-support is given only to working memory elements created by operator-application productions in the state where the operator was selected. -An operator-application production tests the current operator of a state and modifies the -state. Thus, a working memory element receives o-support if it is for an augmentation of -the current state or substructure of the state, and the conditions of the instantiation that -created it test augmentations of the current operator. - -During productions matching, all productions that have their conditions met fire, creating -preferences which may add or remove working memory elements. Also, working memory -elements and preferences that lose i-support are removed from working memory. Thus, -several new working memory elements and preferences may be created, and several existing -working memory elements and preferences may be removed at the same time. (Of course, -all this doesn’t happen literally at the same time, but the order of firings and retractions is -unimportant, and happens in parallel from a functional perspective.) +An operator-application production tests the current operator of a state and +modifies the state. Thus, a working memory element receives o-support if it is +for an augmentation of the current state or substructure of the state, and the +conditions of the instantiation that created it test augmentations of the +current operator. + +During productions matching, all productions that have their conditions met +fire, creating preferences which may add or remove working memory elements. +Also, working memory elements and preferences that lose i-support are removed +from working memory. Thus, several new working memory elements and preferences +may be created, and several existing working memory elements and preferences may +be removed at the same time. (Of course, all this doesn’t happen literally at +the same time, but the order of firings and retractions is unimportant, and +happens in parallel from a functional perspective.) ## Preference Memory: Selection Knowledge The selection of the current operator is determined by the **preferences** in -*preference memory*. Preferences are suggestions or imperatives about the current +_preference memory_. Preferences are suggestions or imperatives about the current operator, or information about how suggested operators compare to other operators. Preferences refer to operators by using the identifier of a working memory element that stands for the operator. After preferences have been created for a state, the decision procedure evaluates them to select the current operator for that state. -For an operator to be selected, there will be at least one preference for it, specifically, a -preference to say that the value is a candidate for the operator attribute of a state (this is -done with either an `"acceptable` or `"require"` preference). There may also be others, for -example to say that the value is "best". +For an operator to be selected, there will be at least one preference for it, +specifically, a preference to say that the value is a candidate for the operator +attribute of a state (this is done with either an `"acceptable` or `"require"` +preference). There may also be others, for example to say that the value is +"best". -Preferences remain in preference memory until removed for one of the reasons previously -discussed in [Production Actions and Persistence](#production-actions-and-persistence). +Preferences remain in preference memory until removed for one of the reasons +previously discussed in [Production Actions and +Persistence](#production-actions-and-persistence). ### Preference Semantics -This section describes the semantics of each type of preference. More details on the preference -resolution process are provided in [How preferences are evaluated to decide an operator](#how-preferences-are-evaluated-to-decide-an-operator). - -Only a single value can be selected as the current operator, that is, all values are mutually -exclusive. In addition, there is no implicit transitivity in the semantics of preferences. If A -is indifferent to B, and B is indifferent to C, A and C will not be indifferent to one another -unless there is a preference that A is indifferent to C (or C and A are both indifferent to all -competing values). - -- **Acceptable (+)** An `acceptable` preference states that a value is a candidate for selection. -All values, except those with require preferences, must have an `acceptable` preference -in order to be selected. If there is only one value with an `acceptable` preference (and -none with a require preference), that value will be selected as long as it does not also -have a reject or a prohibit preference. - -- **Reject (-)** A `reject` preference states that the value is not a candidate for selection. - -- **Better (`>value`), Worse (`value`), Worse (`)** A `best` preference states that the value may be better than any -competing value (unless there are other competing values that are also "best"). -If a value is `best` (and not `rejected`, `prohibited`, or worse than another), it will -be selected over any other value that is not also `best` (or required). If two such -values are `best`, then any remaining preferences for those candidates -(worst,indifferent) will be examined to determine the selection. Note that if a -value (that is not `rejected` or `prohibited`) is better than a `best` value, the -better value will be selected. (This result is counter- intuitive, but allows -explicit knowledge about the relative worth of two values to dominate knowledge -of only a single value. A require preference should be used when a value must be -selected for the goal to be achieved.) - -- **Worst (<)** A `worst` preference states that the value should be selected only if there are no -alternatives. It allows for a simple type of default specification. The semantics of the -worst preference are similar to those for the `best` preference. + competing value (unless there are other competing values that are also "best"). + If a value is `best` (and not `rejected`, `prohibited`, or worse than another), + it will be selected over any other value that is not also `best` (or required). + If two such values are `best`, then any remaining preferences for those + candidates (worst,indifferent) will be examined to determine the selection. Note + that if a value (that is not `rejected` or `prohibited`) is better than a `best` + value, the better value will be selected. (This result is counter- intuitive, + but allows explicit knowledge about the relative worth of two values to dominate + knowledge of only a single value. A require preference should be used when a + value must be selected for the goal to be achieved.) + +- **Worst (<)** A `worst` preference states that the value should be selected + only if there are no alternatives. It allows for a simple type of default + specification. The semantics of the worst preference are similar to those for + the `best` preference. - **Unary Indifferent (=)** A `unary indifferent` preference states that there -is positive knowledge that a single value is as good or as bad a choice as other -expected alternatives. When two or more competing values both have indifferent -preferences, by default, Soar chooses randomly from among the alternatives. (The -[`decide indifferent-selection` function](../reference/cli/cmd_decide.md) can be used to change this behavior). - -- **Binary Indifferent (=value)** A `binary indifferent` preference states that two values -are mutually indifferent and it does not matter which of these values are selected. It -behaves like a unary in different preference, except that the operator value given -this preference is only made indifferent to the operator value given as the argument. + is positive knowledge that a single value is as good or as bad a choice as other + expected alternatives. When two or more competing values both have indifferent + preferences, by default, Soar chooses randomly from among the alternatives. (The + [`decide indifferent-selection` function](../reference/cli/cmd_decide.md) can be + used to change this behavior). + +- **Binary Indifferent (=value)** A `binary indifferent` preference states that + two values are mutually indifferent and it does not matter which of these values + are selected. It behaves like a unary in different preference, except that the + operator value given this preference is only made indifferent to the operator + value given as the argument. - **Numeric-Indifferent (=number)** A `numeric-indifferent` preference is used -to bias the random selection from mutually indifferent values. This preference -includes a unary indifferent preference, and behaves in that manner when -competing with another value having a unary indifferent preference. But when a -set of competing operator values have `numeric-indifferent` preferences, the -decision mechanism will choose an operator based on their numeric-indifferent -values and the exploration policy. The available exploration policies and how -they calculate selection probability are detailed in the [documentation for the -indifferent-selection command](../reference/cli/cmd_decide.md). When a single operator is -given multiple `numeric-indifferent` preferences, they are either averaged or -summed into a single value based on the setting of the -[`numeric-indifferent-mode` command](../reference/cli/cmd_decide.md). Numeric-indifferent -preferences that are created by RL rules can be adjusted by the reinforcement -learning mechanism. In this way, it’s possible for an agent to begin a task with -only arbitrarily initialized numeric indifferent preferences and with experience -learn to make the optimal decisions. See chapter 5 for more information. - -- **Require (!)** A `require` preference states that the value must be selected if the goal is to be -achieved. A `required` value is preferred over all others. Only a single operator value -should be given a `require` preference at a time. - -- **Prohibit (~)** A `prohibit` preference states that the value cannot be selected if the goal is -to be achieved. If a value has a prohibit preference, it will not be selected for a value -of an augmentation, independent of the other preferences. - -If there is an `acceptable` preference for a value of an operator, and there are no other -competing values, that operator will be selected. If there are multiple `acceptable` preferences -for the same state but with different values, the preferences must be evaluated to determine -which candidate is selected. - -If the preferences can be evaluated without conflict, the appropriate operator augmentation -of the state will be added to working memory. This can happen when they all suggest the -same operator or when one operator is preferable to the others that have been suggested. -When the preferences conflict, Soar reaches an impasse, as described in [Impasses and Substates](#impasses-and-substates). - -Preferences can be confusing; for example, there can be two suggested values that are both -"best" (which again will lead to an impasse unless additional preferences resolve this conflict); -or there may be one preference to say that value A is better than valueB and a second -preference to say that value B is better than valueA. + to bias the random selection from mutually indifferent values. This preference + includes a unary indifferent preference, and behaves in that manner when + competing with another value having a unary indifferent preference. But when a + set of competing operator values have `numeric-indifferent` preferences, the + decision mechanism will choose an operator based on their numeric-indifferent + values and the exploration policy. The available exploration policies and how + they calculate selection probability are detailed in the [documentation for the + indifferent-selection command](../reference/cli/cmd_decide.md). When a single + operator is given multiple `numeric-indifferent` preferences, they are either + averaged or summed into a single value based on the setting of the + [`numeric-indifferent-mode` command](../reference/cli/cmd_decide.md). + Numeric-indifferent preferences that are created by RL rules can be adjusted by + the reinforcement learning mechanism. In this way, it’s possible for an agent to + begin a task with only arbitrarily initialized numeric indifferent preferences + and with experience learn to make the optimal decisions. See chapter 5 for more + information. + +- **Require (!)** A `require` preference states that the value must be selected + if the goal is to be achieved. A `required` value is preferred over all others. + Only a single operator value should be given a `require` preference at a time. + +- **Prohibit (~)** A `prohibit` preference states that the value cannot be + selected if the goal is to be achieved. If a value has a prohibit preference, it + will not be selected for a value of an augmentation, independent of the other + preferences. + +If there is an `acceptable` preference for a value of an operator, and there are +no other competing values, that operator will be selected. If there are multiple +`acceptable` preferences for the same state but with different values, the +preferences must be evaluated to determine which candidate is selected. + +If the preferences can be evaluated without conflict, the appropriate operator +augmentation of the state will be added to working memory. This can happen when +they all suggest the same operator or when one operator is preferable to the +others that have been suggested. When the preferences conflict, Soar reaches an +impasse, as described in [Impasses and Substates](#impasses-and-substates). + +Preferences can be confusing; for example, there can be two suggested values +that are both "best" (which again will lead to an impasse unless additional +preferences resolve this conflict); or there may be one preference to say that +value A is better than valueB and a second preference to say that value B is +better than valueA. ### How preferences are evaluated to decide an operator -During the decision phase, operator preferences are evaluated in a sequence of eight steps, -in an effort to select a single operator. Each step handles a specific type of preference, as -illustrated in Figure 2.8. (The figure should be read starting at the top where all the operator -preferences are collected and passed into the procedure. At each step, the procedure either -exits through a arrow to the right, or passes to the next step through an arrow to the left.) +During the decision phase, operator preferences are evaluated in a sequence of +eight steps, in an effort to select a single operator. Each step handles a +specific type of preference, as illustrated in Figure 2.8. (The figure should be +read starting at the top where all the operator preferences are collected and +passed into the procedure. At each step, the procedure either exits through a +arrow to the right, or passes to the next step through an arrow to the left.) -Input to the procedure is the set of current operator preferences, and the output consists of: +Input to the procedure is the set of current operator preferences, and the +output consists of: -1. A subset of the candidate operators, which is either the empty set, a single, winning - candidate, or a larger set of candidates that may be conflicting, tied, or indifferent. +1. A subset of the candidate operators, which is either the empty set, a single, + winning candidate, or a larger set of candidates that may be conflicting, tied, + or indifferent. 2. An impasse-type. -The procedure has several potential exit points. Some occur when the procedure has detected -a particular type of impasse. The others occur when the number of candidates has been -reduced to one (necessarily the winner) or zero (a no-change impasse). +The procedure has several potential exit points. Some occur when the procedure +has detected a particular type of impasse. The others occur when the number of +candidates has been reduced to one (necessarily the winner) or zero (a no-change +impasse). ![An illustration of the preference resolution process. There are eight steps; only five of these provide exits from the resolution process.](Images/newprefsem.svg) + /// caption -An illustration of the preference resolution process. There are eight steps; only five of these provide exits from the resolution process. +An illustration of the preference resolution process. There are eight steps; +only five of these provide exits from the resolution process. /// Each step in Figure 2.8 is described below: -- **RequireTest (!)** This test checks for required candidates in preference memory and also -constraint-failure impasses involving require preferences, cf. [Impasses and Substates](#impasses-and-substates). - - If there is exactly one candidate operator with a require preference and that - candidate does not have a prohibit preference, then that candidate is the winner - and preference semantics terminates. - - Otherwise — If there is more than one required candidate, then a constraint- - failure impasse is recognized and preference semantics terminates by returning - the set of required candidates. - - Otherwise — If there is a required candidate that is also prohibited, a constraint- - failure impasse with the required/prohibited value is recognized and preference - semantics terminates. - - Otherwise — There is no required candidate; candidates are passed to AcceptableCollect. - -- **AcceptableCollect (+)** This operation builds a list of operators for which there is an -acceptable preference in preference memory. This list of candidate operators is passed -to the ProhibitFilter. - -- **ProhibitFilter (~)** This filter removes the candidates that have prohibit preferences in -memory. The rest of the candidates are passed to the RejectFilter. - -- **RejectFilter (-)** This filter removes the candidates that have reject preferences in mem- -ory. - -- **Exit Point 1**: - - At this point, if the set of remaining candidates is empty, a no-change impasse is - created with no operators being selected. - - If the set has one member, preference semantics terminates and this set is re- - turned. - - Otherwise, the remaining candidates are passed to the BetterWorseFilter. - -- **BetterWorseFilter (>), (<)** This filter removes any candidates that are worse than an- -other candidate. - -- **Exit point 2**: - - If the set of remaining candidates is empty, a conflict impasse is created returning - the set of all candidates passed into this filter, i.e. all of the conflicted operators. - - If the set of remaining candidates has one member, preference semantics terminates and this set is returned. - - Otherwise, the remaining candidates are passed to the BestFilter. - -- **BestFilter (>)** If some remaining candidate has a best preference, this filter removes any -candidates that do not have a best preference. If there are no best preferences for any -of the current candidates, the filter has no effect. The remaining candidates are passed -to the WorstFilter. - -- **Exit Point 3**: - - At this point, if the set of remaining candidates is empty, a no-change impasse is - created with no operators being selected. - - If the set has one member, preference semantics terminates and this set is re- - turned. - - Otherwise, the remaining candidates are passed to the WorstFilter. - -- **WorstFilter (<)** This filter removes any candidates that have a `worst` preference. If all - remaining candidates have `worst` preferences or there are no `worst` preferences, this - filter has no effect. - -- **Exit Point 4**: - - At this point, if the set of remaining candidates is empty, a no-change impasse is - created with no operators being selected. - - If the set has one member, preference semantics terminates and this set is re- - turned. - - Otherwise, the remaining candidates are passed to the IndifferentFilter. - -- **IndifferentFilter (=)** This operation traverses the remaining candidates and marks each - candidate for which one of the following is true: - - the candidate has a unary indifferent preference - - the candidate has a numeric indifferent preference - -This filter then checks every candidate that is not one of the above two types to see if it -has a binary indifferent preference with every other candidate. If one of the candidates -fails this test, then the procedure signals a tie impasse and returns the complete set of -candidates that were passed into the IndifferentFilter. Otherwise, the candidates are -mutually indifferent, in which case an operator is chosen according to the method set -by the [`decide indifferent-selection` command](../reference/cli/cmd_decide.md). +- **RequireTest (!)** This test checks for required candidates in preference + memory and also constraint-failure impasses involving require preferences, cf. + [Impasses and Substates](#impasses-and-substates). - If there is exactly one + candidate operator with a require preference and that candidate does not have a + prohibit preference, then that candidate is the winner and preference semantics + terminates. - Otherwise — If there is more than one required candidate, then a + constraint- failure impasse is recognized and preference semantics terminates by + returning the set of required candidates. - Otherwise — If there is a required + candidate that is also prohibited, a constraint- failure impasse with the + required/prohibited value is recognized and preference semantics terminates. - + Otherwise — There is no required candidate; candidates are passed to + AcceptableCollect. + +- **AcceptableCollect (+)** This operation builds a list of operators for which + there is an acceptable preference in preference memory. This list of candidate + operators is passed to the ProhibitFilter. + +- **ProhibitFilter (~)** This filter removes the candidates that have prohibit + preferences in memory. The rest of the candidates are passed to the + RejectFilter. + +- **RejectFilter (-)** This filter removes the candidates that have reject + preferences in mem- ory. + +- **Exit Point 1**: - At this point, if the set of remaining candidates is + empty, a no-change impasse is created with no operators being selected. - If the + set has one member, preference semantics terminates and this set is re- turned. +- Otherwise, the remaining candidates are passed to the BetterWorseFilter. + +- **BetterWorseFilter (>), (<)** This filter removes any candidates that are + worse than an- other candidate. + +- **Exit point 2**: - If the set of remaining candidates is empty, a conflict + impasse is created returning the set of all candidates passed into this filter, + i.e. all of the conflicted operators. - If the set of remaining candidates has + one member, preference semantics terminates and this set is returned. - + Otherwise, the remaining candidates are passed to the BestFilter. + +- **BestFilter (>)** If some remaining candidate has a best preference, this + filter removes any candidates that do not have a best preference. If there are + no best preferences for any of the current candidates, the filter has no effect. + The remaining candidates are passed to the WorstFilter. + +- **Exit Point 3**: - At this point, if the set of remaining candidates is + empty, a no-change impasse is created with no operators being selected. - If the + set has one member, preference semantics terminates and this set is re- turned. +- Otherwise, the remaining candidates are passed to the WorstFilter. + +- **WorstFilter (<)** This filter removes any candidates that have a `worst` + preference. If all remaining candidates have `worst` preferences or there are no + `worst` preferences, this filter has no effect. + +- **Exit Point 4**: - At this point, if the set of remaining candidates is + empty, a no-change impasse is created with no operators being selected. - If the + set has one member, preference semantics terminates and this set is re- turned. +- Otherwise, the remaining candidates are passed to the IndifferentFilter. + +- **IndifferentFilter (=)** This operation traverses the remaining candidates + and marks each candidate for which one of the following is true: - the candidate + has a unary indifferent preference - the candidate has a numeric indifferent + preference + +This filter then checks every candidate that is not one of the above two types +to see if it has a binary indifferent preference with every other candidate. If +one of the candidates fails this test, then the procedure signals a tie impasse +and returns the complete set of candidates that were passed into the +IndifferentFilter. Otherwise, the candidates are mutually indifferent, in which +case an operator is chosen according to the method set by the [`decide +indifferent-selection` command](../reference/cli/cmd_decide.md). ## Soar’s Execution Cycle: Without Substates @@ -776,69 +856,77 @@ cycle has five phases: these productions are i-supported. All matched productions fire in parallel (and all retractions occur in parallel), and matching and firing continues until there are no more additional complete matches or retractions of productions - (*quiescence*). -3. **Decision**: A new operator is selected, or an impasse is detected and a new state is - created. -4. **Application**: Productions fire to apply the operator (operator application). - The actions of these productions will be o-supported. Because of changes from - operator application productions, other productions with i-supported actions may - also match or retract. Just as during proposal, productions fire and retract in - parallel until quiescence. + (_quiescence_). +3. **Decision**: A new operator is selected, or an impasse is detected and a new + state is created. +4. **Application**: Productions fire to apply the operator (operator + application). The actions of these productions will be o-supported. Because of + changes from operator application productions, other productions with + i-supported actions may also match or retract. Just as during proposal, + productions fire and retract in parallel until quiescence. 5. **Output**: Output commands are sent to the external environment. -The cycles continue until the halt action is issued from the Soar program (as the action of -a production) or until Soar is interrupted by the user. +The cycles continue until the halt action is issued from the Soar program (as +the action of a production) or until Soar is interrupted by the user. -An important aspect of productions in Soar to keep in mind is that all productions will -always fire whenever their conditions are met, and retract whenever their conditions are no -longer met. The exact details of this process are shown in Figure 2.9. The *Proposal* and -*Application* phases described above are both composed of as many **elaboration cycles** as -are necessary to reach quiescence. In each elaboration cycle, all matching productions fire -and the working memory changes or operator preferences described through their actions are -made. After each elaboration cycle, if the working memory changes just made change the -set of matching productions, another cycle ensues. This repeats until the set of matching -rules remains unchanged, a situation called **quiescence**. +An important aspect of productions in Soar to keep in mind is that all +productions will always fire whenever their conditions are met, and retract +whenever their conditions are no longer met. The exact details of this process +are shown in Figure 2.9. The _Proposal_ and _Application_ phases described above +are both composed of as many **elaboration cycles** as are necessary to reach +quiescence. In each elaboration cycle, all matching productions fire and the +working memory changes or operator preferences described through their actions +are made. After each elaboration cycle, if the working memory changes just made +change the set of matching productions, another cycle ensues. This repeats until +the set of matching rules remains unchanged, a situation called **quiescence**. ![A detailed illustration of Soar’s decision cycle.](Images/decisioncycle.svg) + /// caption A detailed illustration of Soar’s decision cycle. /// -After quiescence is reached in the *Proposal* phase, the *Decision* phase ensues, which is the -architectural selection of a single operator, if possible. Once an operator is selected, the -*Apply* phase ensues, which is practically the same as the *Proposal* phase, except that any -productions that apply the chosen operator (they test for the selection of that operator in -their conditions) will now match and fire. - -During the processing of these phases, it is possible that the preferences that resulted in -the selection of the current operator could change. Whenever operator preferences change, -the preferences are re-evaluated and if a different operator selection would be made, then -the current operator augmentation of the state is immediately removed. However, a new -operator is not selected until the next decision phase, when all knowledge has had a chance -to be retrieved. In other words, if, during the *Apply* phase, the production(s) that proposed -the selected operator retract, that *Apply* phase will immediately end. +After quiescence is reached in the _Proposal_ phase, the _Decision_ phase +ensues, which is the architectural selection of a single operator, if possible. +Once an operator is selected, the _Apply_ phase ensues, which is practically the +same as the _Proposal_ phase, except that any productions that apply the chosen +operator (they test for the selection of that operator in their conditions) will +now match and fire. + +During the processing of these phases, it is possible that the preferences that +resulted in the selection of the current operator could change. Whenever +operator preferences change, the preferences are re-evaluated and if a different +operator selection would be made, then the current operator augmentation of the +state is immediately removed. However, a new operator is not selected until the +next decision phase, when all knowledge has had a chance to be retrieved. In +other words, if, during the _Apply_ phase, the production(s) that proposed the +selected operator retract, that _Apply_ phase will immediately end. ## Input and Output -Many Soar users will want their programs to interact with a real or simulated environment. -For example, Soar programs may control a robot, receiving sensory inputs and sending -command outputs. Soar programs may also interact with simulated environments, such as a -flight simulator. Input is viewed as Soar’s perception and output is viewed as Soar’s motor -abilities. +Many Soar users will want their programs to interact with a real or simulated +environment. For example, Soar programs may control a robot, receiving sensory +inputs and sending command outputs. Soar programs may also interact with +simulated environments, such as a flight simulator. Input is viewed as Soar’s +perception and output is viewed as Soar’s motor abilities. -When Soar interacts with an external environment, it must make use of mechanisms that -allow it to receive input from that environment and to effect changes in that environment; -the mechanisms provided in Soar are called input functions and output functions. +When Soar interacts with an external environment, it must make use of mechanisms +that allow it to receive input from that environment and to effect changes in +that environment; the mechanisms provided in Soar are called input functions and +output functions. -- **Input functions** add and delete elements from working memory in response to changes in -the external environment. +- **Input functions** add and delete elements from working memory in response to + changes in the external environment. - **Output functions** attempt to effect changes in the external environment. -Input is processed at the beginning of each execution cycle and output occurs at the end of -each execution cycle. See [Soar I/O: Input and Output in Soar](./03_SyntaxOfSoarPrograms.md#soar-io-input-and-output-in-soar) for more information. +Input is processed at the beginning of each execution cycle and output occurs at +the end of each execution cycle. See [Soar I/O: Input and Output in +Soar](./03_SyntaxOfSoarPrograms.md#soar-io-input-and-output-in-soar) for more +information. A simplified version of the Soar algorithm: -``` + +``` txt Soar while (HALT not true) Cycle; @@ -887,229 +975,271 @@ There are four types of impasses that can arise from the preference scheme. #### Tie impasse -A *tie* impasse arises if the preferences do not distinguish between two or more +A _tie_ impasse arises if the preferences do not distinguish between two or more operators that have `acceptable` preferences. If two operators both have best or worst preferences, they will tie unless additional preferences distinguish between them. #### Conflict impasse -A *conflict* impasse arises if at least two values have conflicting better or +A _conflict_ impasse arises if at least two values have conflicting better or worse preferences (such as A is better than B and B is better than A) for an operator, and neither one is rejected, prohibited, or required. #### Constraint-failure impasse -A *constraint-failure* impasse arises if there is more than one `required` value for -an operator, or if a value has both a `require` and a `prohibit` preference. These -preferences represent constraints on the legal selections that can be made for a -decision and if they conflict, no progress can be made from the current +A _constraint-failure_ impasse arises if there is more than one `required` value +for an operator, or if a value has both a `require` and a `prohibit` preference. +These preferences represent constraints on the legal selections that can be made +for a decision and if they conflict, no progress can be made from the current situation and the impasse cannot be resolved by additional preferences. #### No-change impasse -A *no-change* impasse arises if a new operator is not selected during + +A _no-change_ impasse arises if a new operator is not selected during the decision procedure. There are two types of no-change impasses: - A **State no-change impasse** occurs when there are no `acceptable` (or `require`) -preferences to suggest operators for the current state (or all the `acceptable` -values have also been rejected). The decision procedure cannot select a new -operator. + preferences to suggest operators for the current state (or all the `acceptable` + values have also been rejected). The decision procedure cannot select a new + operator. -- A **Operator no-change impasse** occurs when either a new operator is selected for -the current state but no additional productions match during the application -phase, or a new operator is not selected during the next decision phase. +- A **Operator no-change impasse** occurs when either a new operator is selected + for the current state but no additional productions match during the application + phase, or a new operator is not selected during the next decision phase. -There can be only one type of impasse at a given level of subgoaling at a time. Given the -semantics of the preferences, it is possible to have a tie or conflict impasse and a constraint- -failure impasse at the same time. In these cases, Soar detects only the constraint-failure -impasse. +There can be only one type of impasse at a given level of subgoaling at a time. +Given the semantics of the preferences, it is possible to have a tie or conflict +impasse and a constraint- failure impasse at the same time. In these cases, Soar +detects only the constraint-failure impasse. -The impasse is detected *during* the selection of the operator, but happens +The impasse is detected _during_ the selection of the operator, but happens because one of the four problem-solving functions (described in [Problem-Solving function in Soar](#problem-solving-functions-in-soar)) was incomplete. ### Creating New States -Soar handles these inconsistencies by creating a new state, called a **substate** in which the -goal of the problem solving is to resolve the impasse. Thus, in the substate, operators will -be selected and applied in an attempt either to discover which of the tied operators should -be selected, or to apply the selected operator piece by piece. The substate is often called a -subgoal because it exists to resolve the impasse, but is sometimes called a substate because -the representation of the subgoal in Soar is as a state. - -The initial state in the subgoal contains a complete description of the cause of the impasse, -such as the operators that could not be decided among (or that there were no operators -proposed) and the state that the impasse arose in. From the perspective of the new state, -the latter is called the `superstate`. Thus, the `superstate` is part of the substructure of each -state, represented by the Soar architecture using the `superstate` attribute. (The initial -state, created in the 0th decision cycle, contains a `superstate` attribute with the value of +Soar handles these inconsistencies by creating a new state, called a +**substate** in which the goal of the problem solving is to resolve the impasse. +Thus, in the substate, operators will be selected and applied in an attempt +either to discover which of the tied operators should be selected, or to apply +the selected operator piece by piece. The substate is often called a subgoal +because it exists to resolve the impasse, but is sometimes called a substate +because the representation of the subgoal in Soar is as a state. + +The initial state in the subgoal contains a complete description of the cause of +the impasse, such as the operators that could not be decided among (or that +there were no operators proposed) and the state that the impasse arose in. From +the perspective of the new state, the latter is called the `superstate`. Thus, +the `superstate` is part of the substructure of each state, represented by the +Soar architecture using the `superstate` attribute. (The initial state, created +in the 0th decision cycle, contains a `superstate` attribute with the value of `nil` - the top-level state has no superstate.) -The knowledge to resolve the impasse may be retrieved by any type of problem solving, from -searching to discover the implications of different decisions, to asking an outside agent for -advice. There is no *a priori* restriction on the processing, except that it involves applying -operators to states. +The knowledge to resolve the impasse may be retrieved by any type of problem +solving, from searching to discover the implications of different decisions, to +asking an outside agent for advice. There is no _a priori_ restriction on the +processing, except that it involves applying operators to states. -In the substate, operators can be selected and applied as Soar attempts to solve the sub- -goal. (The operators proposed for solving the subgoal may be similar to the operators in -the superstate, or they may be entirely different.) While problem solving in the subgoal, -additional impasses may be encountered, leading to new subgoals. Thus, it is possible for -Soar to have a stack of subgoals, represented as states: Each state has a single superstate -(except the initial state) and each state may have at most one substate. Newly created -subgoals are considered to be added to the bottom of the stack; the first state is therefore -called the *top-level state.*[3](#footnote3) See Figure 2.11 for a simplified illustrations of a subgoal stack. +In the substate, operators can be selected and applied as Soar attempts to solve +the sub- goal. (The operators proposed for solving the subgoal may be similar to +the operators in the superstate, or they may be entirely different.) While +problem solving in the subgoal, additional impasses may be encountered, leading +to new subgoals. Thus, it is possible for Soar to have a stack of subgoals, +represented as states: Each state has a single superstate (except the initial +state) and each state may have at most one substate. Newly created subgoals are +considered to be added to the bottom of the stack; the first state is therefore +called the _top-level state._ See Figure 2.11 for a +simplified illustrations of a subgoal stack. + +!!! note + + The original state is the "top" of the stack because as Soar runs, this state + (created first), will be at the top of the computer screen, and substates + will appear on the screen below the top-level state. ![A simplified illustration of a subgoal stack.](Images/stack1.svg) + /// caption A simplified illustration of a subgoal stack. /// -Soar continually attempts to retrieve knowledge relevant to all goals in the subgoal stack, -although problem-solving activity will tend to focus on the most recently created state. -However, problem solving is active at all levels, and productions that match at any level will -fire. +Soar continually attempts to retrieve knowledge relevant to all goals in the +subgoal stack, although problem-solving activity will tend to focus on the most +recently created state. However, problem solving is active at all levels, and +productions that match at any level will fire. ### Results -In order to resolve impasses, subgoals must generate results that allow the problem solving -at higher levels to proceed. The **results** of a subgoal are the working memory elements and -preferences that were created in the substate, and that are also linked directly or indirectly -to a superstate (any superstate in the stack). A preference or working memory element is -said to be created in a state if the production that created it tested that state and this is -the most recent state that the production tested. Thus, if a production tests multiple states, -the preferences and working memory elements in its actions are considered to be created in -the most recent of those states (the lowest-level state) and is not considered to have been -created in the other states. The architecture automatically detects if a preference or working -memory element created in a substate is also linked to a superstate. - -These working memory elements and preferences will not be removed when the impasse is -resolved because they are still linked to a superstate, and therefore, they are called the *results -of the subgoal*. A result has either i-support or o-support; the determination of support is -described below. - -A working memory element or preference will be a result if its identifier is already linked to -a superstate. A working memory element or preference can also become a result indirectly -if, after it is created and it is still in working memory or preference memory, its identifier -becomes linked to a superstate through the creation of another result. For example, if the -problem solving in a state constructs an operator for a superstate, it may wait until the -operator structure is complete before creating an `acceptable` preference for the operator in -the superstate. The `acceptable` preference is a result because it was created in the state -and is linked to the superstate (and, through the superstate, is linked to the top-level state). -The substructures of the operator then become results because the operator’s identifier is -now linked to the superstate. +In order to resolve impasses, subgoals must generate results that allow the +problem solving at higher levels to proceed. The **results** of a subgoal are +the working memory elements and preferences that were created in the substate, +and that are also linked directly or indirectly to a superstate (any superstate +in the stack). A preference or working memory element is said to be created in a +state if the production that created it tested that state and this is the most +recent state that the production tested. Thus, if a production tests multiple +states, the preferences and working memory elements in its actions are +considered to be created in the most recent of those states (the lowest-level +state) and is not considered to have been created in the other states. The +architecture automatically detects if a preference or working memory element +created in a substate is also linked to a superstate. + +These working memory elements and preferences will not be removed when the +impasse is resolved because they are still linked to a superstate, and +therefore, they are called the _results of the subgoal_. A result has either +i-support or o-support; the determination of support is described below. + +A working memory element or preference will be a result if its identifier is +already linked to a superstate. A working memory element or preference can also +become a result indirectly if, after it is created and it is still in working +memory or preference memory, its identifier becomes linked to a superstate +through the creation of another result. For example, if the problem solving in a +state constructs an operator for a superstate, it may wait until the operator +structure is complete before creating an `acceptable` preference for the +operator in the superstate. The `acceptable` preference is a result because it +was created in the state and is linked to the superstate (and, through the +superstate, is linked to the top-level state). The substructures of the +operator then become results because the operator’s identifier is now linked to +the superstate. ### Justifications: Support for results Recall from section [Production Actions and -Persistance](#production-actions-and-persistence) that WMEs with *i-support* +Persistance](#production-actions-and-persistence) that WMEs with _i-support_ disappear as soon as the production that created them -retract,[4](#footnote4) whereas WMEs with *o-support* (created +retract, whereas WMEs with _o-support_ (created through applying an operator) persist in working memory until deliberately removed. -Some results receive i-support, while others receive o-support. The type of support received -by a result is determined by the function it plays in the superstate, and not the function it -played in the state in which it was created. For example, a result might be created through -operator application in the state that created it; however, it might only be a state elaboration -in the superstate. The first function would lead to o-support, but the second would lead to -i-support. - -In order for the architecture to determine whether a result receives i-support or o-support, -Soar must first determine the function that the working memory element or preference plays -(that is, whether the result should be considered an operator application or not). To do this, -Soar creates a temporary production, called a **justification**. The justification summarizes -the processing in the substate that led to the result: - -- **The conditions** of a justification are those working memory elements that exist in the -superstate (and above) that were necessary for producing the result. This is determined -by collecting all of the working memory elements tested by the productions that fired -in the subgoal that led to the creation of the result, and then removing those conditions -that test working memory elements created in the subgoal. +!!! note + + Technically, an i-supported WME is only retracted when it loses instantiation + support, not when the creating production is retracting. For example, a WME + could receive i-support from several different instantiated productions and + the retraction of only one would not lead to the retraction of the WME. If + such a result loses i-support from the justification, it will be retracted if + there is no other support. + +Some results receive i-support, while others receive o-support. The type of +support received by a result is determined by the function it plays in the +superstate, and not the function it played in the state in which it was created. +For example, a result might be created through operator application in the state +that created it; however, it might only be a state elaboration in the +superstate. The first function would lead to o-support, but the second would +lead to i-support. + +In order for the architecture to determine whether a result receives i-support +or o-support, Soar must first determine the function that the working memory +element or preference plays (that is, whether the result should be considered an +operator application or not). To do this, Soar creates a temporary production, +called a **justification**. The justification summarizes the processing in the +substate that led to the result: + +- **The conditions** of a justification are those working memory elements that + exist in the superstate (and above) that were necessary for producing the + result. This is determined by collecting all of the working memory elements + tested by the productions that fired in the subgoal that led to the creation of + the result, and then removing those conditions that test working memory elements + created in the subgoal. - **The action** of the justification is the result of the subgoal. -Thus, when the substate disappears, the generated justification serves as the production that -supports any subgoal results. +Thus, when the substate disappears, the generated justification serves as the +production that supports any subgoal results. Soar determines i-support or o-support for the justification and its actions -just as it would for any other production, as described in section -[Production Actions and Persistence](#production-actions-and-persistence). -If the justification is an operator application, the result will receive -o-support. Otherwise, the result gets i-support from the justification. If such -a result loses i-support from the justification, it will be retracted if there -is no other support. +just as it would for any other production, as described in section [Production +Actions and Persistence](#production-actions-and-persistence). If the +justification is an operator application, the result will receive o-support. +Otherwise, the result gets i-support from the justification. If such a result +loses i-support from the justification, it will be retracted if there is no +other support. Justifications include any negated conditions that were in the original productions that participated in producing the results, and that test for the absence of superstate working memory elements. Negated conditions that test for the absence of working memory elements that are local to the substate are not included, which can lead to overgeneralization in the justification (see -Sections [Operational Analysis](./04_ProceduralKnowledgeLearning.md#operationality-analysis) and -[Collapsed Negative Reasoning](./04_ProceduralKnowledgeLearning.md#collapsed-negative-reasoning) for +Sections [Dependency +Analysis](./04_ProceduralKnowledgeLearning.md#dependency-analysis) and +[Collapsed Negative +Reasoning](./04_ProceduralKnowledgeLearning.md#collapsed-negative-reasoning) for details). ### Chunking: Learning Procedural Knowledge -When an operator impasse is resolved, it means that Soar has, through problem solving, -gained access to knowledge that was not readily available before. Therefore, when an impasse -is resolved, Soar has an opportunity to learn, by summarizing and generalizing the processing -in the substate. +When an operator impasse is resolved, it means that Soar has, through problem +solving, gained access to knowledge that was not readily available before. +Therefore, when an impasse is resolved, Soar has an opportunity to learn, by +summarizing and generalizing the processing in the substate. -One of Soar’s learning mechanisms is called **chunking** (See [chapter 4](./04_ProceduralKnowledgeLearning.md) for more information); -it attempts to create a new production, called a **chunk**. The conditions of the chunk are the -elements of the state that (through some chain of production firings) allowed the impasse to -be resolved; the action of the production is the working memory element or preference that -resolved the impasse (the result of the impasse). The conditions and action are variablized -so that this new production may match in a similar situation in the future and prevent an -impasse from arising. +One of Soar’s learning mechanisms is called **chunking** (See [chapter +4](./04_ProceduralKnowledgeLearning.md) for more information); it attempts to +create a new production, called a **chunk**. The conditions of the chunk are the +elements of the state that (through some chain of production firings) allowed +the impasse to be resolved; the action of the production is the working memory +element or preference that resolved the impasse (the result of the impasse). The +conditions and action are variablized so that this new production may match in a +similar situation in the future and prevent an impasse from arising. -Chunks and justifications are very similar in that they both summarize substate results. -They are, in fact, generated by the architecture using the same result dependency trace -mechanisms. However, there are some important distinctions: +Chunks and justifications are very similar in that they both summarize substate +results. They are, in fact, generated by the architecture using the same result +dependency trace mechanisms. However, there are some important distinctions: 1. Justifications disappear as soon as its conditions no longer match. 2. Chunks contain variables so that they may match working memory in other situations; justifications are similar to an instantiated chunk. -In other words, a chunk might be thought of as a permanent and potentially more generalized -form of a justification. Since the result that solves the impasse problem is learned in a -chunk, whenever the agent encounters the same situation again as that which resulted in the -original impasse, it can simply fire the chunk to generate the same result previously derived, -preempting the need for a substate and repeated deliberate problem solving. +In other words, a chunk might be thought of as a permanent and potentially more +generalized form of a justification. Since the result that solves the impasse +problem is learned in a chunk, whenever the agent encounters the same situation +again as that which resulted in the original impasse, it can simply fire the +chunk to generate the same result previously derived, preempting the need for a +substate and repeated deliberate problem solving. ### The calculation of o-support This section provides a more detailed description of when an action is given -o-support by an instantiation.[5](#footnote5) The content here is +o-support by an instantiation. The content here is somewhat more advanced, and the reader unfamiliar with rule syntax (explained in -[Chapter 3](./03_SyntaxOfSoarPrograms.md)) may wish to skip this section and return at a later point. +[Chapter 3](./03_SyntaxOfSoarPrograms.md)) may wish to skip this section and +return at a later point. -Support is given by the production; that is, all working memory changes generated by the -actions of a single instantiated production will have the same support (an action that is not -given o-support will have i-support). The conditions and actions of a production rule will -here be referred to using the shorthand of LHS and RHS (for Left-Hand Side and Right-Hand -Side), respectively. +!!! note + + In the past, Soar had various experimental support mode settings. Since + version 9.6, the support mode used is what was previously called mode 4. + +Support is given by the production; that is, all working memory changes +generated by the actions of a single instantiated production will have the same +support (an action that is not given o-support will have i-support). The +conditions and actions of a production rule will here be referred to using the +shorthand of LHS and RHS (for Left-Hand Side and Right-Hand Side), respectively. A production must meet the following two requirements to have o-supported actions: 1. The RHS has no operator proposals, i.e. nothing of the form - ``` - ( ^operator +) - ``` - -2. The LHS has a condition that tests the current operator, i.e. something of the form - ``` - ( ^operator ) - ``` - -In condition 1, the variable `` must be bound to a state identifier. In condition 2, the -variable `` must be bound to the lowest state identifier. That is to say, each (positive) -condition on the LHS takes the form `(id ^attr value)`, some of these id’s match state -identifiers, and the system looks for the deepest matched state identifier. The tested current -operator must be on this state. For example, in this production, - -```Soar + +``` Soar +( ^operator +) +``` + +1. The LHS has a condition that tests the current operator, i.e. something of + the form + +``` Soar +( ^operator ) +``` + +In condition 1, the variable `` must be bound to a state identifier. In +condition 2, the variable `` must be bound to the lowest state identifier. +That is to say, each (positive) condition on the LHS takes the form `(id ^attr +value)`, some of these id’s match state identifiers, and the system looks for +the deepest matched state identifier. The tested current operator must be on +this state. For example, in this production, + +``` Soar sp {elaborate*state*operator\*name (state ^superstate ) ( ^operator ) @@ -1118,11 +1248,11 @@ sp {elaborate*state*operator\*name ( ^name something)} ``` -the RHS action gets i-support. Of course, the state bound to `` is destroyed when -`( ^operator )` retracts, so o-support would make little difference. On the other hand, this -production, +the RHS action gets i-support. Of course, the state bound to `` is destroyed +when `( ^operator )` retracts, so o-support would make little difference. +On the other hand, this production, -```Soar +``` Soar sp {operator*superstate*application (state ^superstate ) ^operator ) @@ -1131,7 +1261,8 @@ production, ( ^sub-operator-name )} ``` -gives o-support to its RHS action, which remains after the substate bound to `` is destroyed. +gives o-support to its RHS action, which remains after the substate bound to +`` is destroyed. An extension of condition 1 is that operator augmentations should always receive i-support (augmentations define the proposed operator). Soar has been written to @@ -1142,7 +1273,7 @@ operator, adds an operator augmentation, and adds a non-operator augmentation? For example: -```Soar +``` Soar sp {operator*augmentation*application (state ^task test-support ^operator ) @@ -1151,12 +1282,12 @@ sp {operator*augmentation*application ( ^new augmentation)} ``` -In such cases, both receive i-support. Soar will print a warning on firing this production, -because this is considered bad coding style. +In such cases, both receive i-support. Soar will print a warning on firing this +production, because this is considered bad coding style. ### Removal of Substates: Impasse Resolution -Problem solving in substates is an important part of what Soar *does*, and an +Problem solving in substates is an important part of what Soar _does_, and an operator impasse does not necessarily indicate a problem in the Soar program. They are a way to decompose a complex problem into smaller parts and they provide a context for a program to deliberate about which operator to select. @@ -1169,48 +1300,52 @@ impasse from occurring in the first place. #### Resolving Impasses -An impasse is *resolved* when processing in a subgoal creates results that lead to the selection -of a new operator for the state where the impasse arose. When an operator impasse is -resolved, Soar has an opportunity to learn, and the substate (and all its substructure) is -removed from working memory. +An impasse is _resolved_ when processing in a subgoal creates results that lead +to the selection of a new operator for the state where the impasse arose. When +an operator impasse is resolved, Soar has an opportunity to learn, and the +substate (and all its substructure) is removed from working memory. -Here are possible approaches for resolving specific types of impasses are listed below: +Here are possible approaches for resolving specific types of impasses are listed +below: -- **Tie impasse** — A tie impasse can be resolved by productions that create preferences that -prefer one option (`better`, `best`, `require`), eliminate alternatives (`worse`, `worst`, -`reject`,`prohibit`), or make all of the objects indifferent (`indifferent`). +- **Tie impasse** — A tie impasse can be resolved by productions that create + preferences that prefer one option (`better`, `best`, `require`), eliminate + alternatives (`worse`, `worst`, `reject`,`prohibit`), or make all of the objects + indifferent (`indifferent`). - **Conflict impasse** — A conflict impasse can be resolved by productions that -create preferences to require one option (`require`), or eliminate the -alternatives (`reject`, `prohibit`). + create preferences to require one option (`require`), or eliminate the + alternatives (`reject`, `prohibit`). - **Constraint-failure impasse** — A constraint-failure impasse cannot be resolved -by additional preferences, but may be prevented by changing productions so that -they create fewer `require` or `prohibit` preferences. A substate can resolve a -constraint-failure impasse through actions that cause all but one of the -conflicting preferences to retract. + by additional preferences, but may be prevented by changing productions so that + they create fewer `require` or `prohibit` preferences. A substate can resolve a + constraint-failure impasse through actions that cause all but one of the + conflicting preferences to retract. - **State no-change impasse** — A state no-change impasse can be resolved by productions -that create `acceptable` or `require` preferences for operators. + that create `acceptable` or `require` preferences for operators. -- **Operator no-change impasse** — An operator no-change impasse can be resolved by -productions that apply the operator, change the state so the operator proposal -no longer matches, or cause other operators to be proposed and preferred. +- **Operator no-change impasse** — An operator no-change impasse can be resolved + by productions that apply the operator, change the state so the operator + proposal no longer matches, or cause other operators to be proposed and + preferred. #### Eliminating Impasses -An impasse is resolved when results are created that allow progress to be made in the state -where the impasse arose. In Soar, an impasse can be *eliminated* (but not resolved) when -a higher level impasse is resolved, eliminated, or regenerated. In these cases, the impasse -becomes irrelevant because higher-level processing can proceed. An impasse can also become -irrelevant if input from the outside world changes working memory which in turn causes -productions to fire that make it possible to select an operator. In these cases, the impasse -is eliminated, but not "resolved", and Soar does not learn in this situation. +An impasse is resolved when results are created that allow progress to be made +in the state where the impasse arose. In Soar, an impasse can be _eliminated_ +(but not resolved) when a higher level impasse is resolved, eliminated, or +regenerated. In these cases, the impasse becomes irrelevant because higher-level +processing can proceed. An impasse can also become irrelevant if input from the +outside world changes working memory which in turn causes productions to fire +that make it possible to select an operator. In these cases, the impasse is +eliminated, but not "resolved", and Soar does not learn in this situation. -For example, in the blocks-world domain, an agent might deliberate in a substate to deter- -mine whether it should move block A onto block C or block B onto block C in its current -situation. If a child suddenly throws block A out a window, this problem solving becomes -irrelevant, and the impasse is eliminated. +For example, in the blocks-world domain, an agent might deliberate in a substate +to deter- mine whether it should move block A onto block C or block B onto block +C in its current situation. If a child suddenly throws block A out a window, +this problem solving becomes irrelevant, and the impasse is eliminated. #### Regenerating Impasses @@ -1234,7 +1369,7 @@ inconsistency arises, the problem being solved in the subgoal may no longer be the problem that actually needs to be solved. Luckily, not all changes to a superstate lead to inconsistency. -In order to detect inconsistencies, Soar maintains a *Goal Dependency Set* (GDS) +In order to detect inconsistencies, Soar maintains a _Goal Dependency Set_ (GDS) for every subgoal/substate. The dependency set consists of all working memory elements that were tested in the conditions of productions that created o-supported working memory elements that are directly or indirectly linked to @@ -1243,7 +1378,7 @@ substate knowledge). Whenever such an o-supported WME is created, Soar records which superstate WMEs were tested, directly or indirectly, to create it. Whenever any of the WMEs in the dependency set of a substate change, the substate is regenerated. (See Sections -[print](../reference/cli/cmd_print.md#printing-the-goal-dependency-set) and +[print](../reference/cli/cmd_print.md#printing-the-goal-dependency-set) and [trace](../reference/cli/cmd_trace.md#trace-levels) for how to examine GDS information through the user-interface.) @@ -1254,16 +1389,18 @@ and then only when the basis for the creation of those elements changes. #### Substate Removal -Whenever a substate is removed, all working memory elements and preferences that were -created in the substate that are not results are removed from working memory. In Figure -2.11, state `S3` will be removed from working memory when the impasse that created it is -resolved, that is, when sufficient preferences have been generated so that one of the operators -for state `S2` can be selected. When state `S3` is removed, operator `O9` will also be removed, -as will the `acceptable` preferences for `O7`, `O8`, and `O9`, and the `impasse`, `attribute`, and -`choices` augmentations of state `S3`. These working memory elements are removed because -they are no longer linked to the subgoal stack. The `acceptable` preferences for operators `O4`, -`O5`, and `O6` remain in working memory. They were linked to state `S3`, but since they are also -linked to state `S2`, they will stay in working memory until `S2` is removed (or until they are +Whenever a substate is removed, all working memory elements and preferences that +were created in the substate that are not results are removed from working +memory. In Figure 2.11, state `S3` will be removed from working memory when the +impasse that created it is resolved, that is, when sufficient preferences have +been generated so that one of the operators for state `S2` can be selected. When +state `S3` is removed, operator `O9` will also be removed, as will the +`acceptable` preferences for `O7`, `O8`, and `O9`, and the `impasse`, +`attribute`, and `choices` augmentations of state `S3`. These working memory +elements are removed because they are no longer linked to the subgoal stack. The +`acceptable` preferences for operators `O4`, `O5`, and `O6` remain in working +memory. They were linked to state `S3`, but since they are also linked to state +`S2`, they will stay in working memory until `S2` is removed (or until they are retracted or rejected). ### Soar’s Cycle: With Substates @@ -1271,25 +1408,28 @@ retracted or rejected). When there are multiple substates, Soar’s cycle remains basically the same but has a few minor changes. -The main change when there are multiple substates is that at each phase of the decision -cycle, Soar goes through the substates, from oldest (highest) to newest (lowest), completing -any necessary processing at that level for that phase before doing any processing in the next -substate. When firing productions for the proposal or application phases, Soar processes -the firing (and retraction) of rules, starting from those matching the oldest substate to the -newest. Whenever a production fires or retracts, changes are made to working memory -and preference memory, possibly changing which productions will match at the lower levels -(productions firing within a given level are fired in parallel – simulated). Productions firings -at higher levels can resolve impasses and thus eliminate lower states before the productions -at the lower level ever fire. Thus, whenever a level in the state stack is reached, all production -activity is guaranteed to be consistent with any processing that has occurred at higher levels. +The main change when there are multiple substates is that at each phase of the +decision cycle, Soar goes through the substates, from oldest (highest) to newest +(lowest), completing any necessary processing at that level for that phase +before doing any processing in the next substate. When firing productions for +the proposal or application phases, Soar processes the firing (and retraction) +of rules, starting from those matching the oldest substate to the newest. +Whenever a production fires or retracts, changes are made to working memory and +preference memory, possibly changing which productions will match at the lower +levels (productions firing within a given level are fired in parallel – +simulated). Productions firings at higher levels can resolve impasses and thus +eliminate lower states before the productions at the lower level ever fire. +Thus, whenever a level in the state stack is reached, all production activity is +guaranteed to be consistent with any processing that has occurred at higher +levels. ### Removal of Substates: The Goal Dependency Set -This subsection describes the Goal Dependency Set (GDS) with discussions on the motivation -for the GDS and behavioral consequences of the GDS from a developer/modeler’s point of -view. It goes into greater detail than might be beneficial for someone becoming familiar with -the general operation of Soar for the first time. Readers may skip this section and return -later if desired. +This subsection describes the Goal Dependency Set (GDS) with discussions on the +motivation for the GDS and behavioral consequences of the GDS from a +developer/modeler’s point of view. It goes into greater detail than might be +beneficial for someone becoming familiar with the general operation of Soar for +the first time. Readers may skip this section and return later if desired. #### Why the GDS was needed @@ -1301,36 +1441,49 @@ psychology. Those using Soar to create agent systems would like to make Soar’s processing approximate the knowledge level as closely as possible. Soar 7 had a number of symbol-level quirks that appeared inconsistent with human psychology and that made building large-scale, knowledge-based systems in Soar more -difficult than necessary. Bob Wray’s thesis [6](#footnote6) addressed many of these +difficult than necessary. Bob Wray’s thesis addressed many of these symbol-level problems in Soar, among them logical inconsistency in symbol manipulations, non-contemporaneous constraints in chunks , race conditions in rule firings and in the decision process, and contention between original task knowledge and learned knowledge. +!!! note + + Robert E. Wray. Ensuring Reasoning Consistency in Hierarchical Architectures. + PhD thesis, University of Michigan, 1998. + The Goal Dependency Set implements a solution to logical inconsistencies between persis- tent (o-supported) WMEs in a substate and its "context". The context -consists of all the WMEs in any superstates above the local goal/state.[7](#footnote7) In +consists of all the WMEs in any superstates above the local goal/state. In Soar, any action (application) of an operator receives an o-support preference. This preference makes the resulting WME persistent: it will remain in memory until explicitly removed or until its local state is removed, regardless of whether it continues to be justified. -Persistent WMEs are pervasive in Soar, because operators are the main unit of problem -solving. Persistence is necessary for taking any non-monotonic step in a problem space. -However, persistent WMEs also are dependent on WMEs in the superstate context. The -problem in Soar prior to GDS, especially when trying to create a large-scale system, is that -the knowledge developer must always think about which dependencies can be "ignored" -and which may affect the persistent WME. For example, imagine an exploration robot that -makes a persistent decision to travel to some distant destination based, in part, on its power -reserves. Now suppose that the agent notices that its power reserves have failed. If this -change is not communicated to the state where the travel decision was made, the agent will -continue to act as if its full power reserves were still available. +!!! note + + This subsection will primarily use "state," not "goal." While these terms are + often used nearly-interchangeably in the context of Soar, states refer to the + set of WMEs comprising knowledge related to a peculiar level of goal. The Goal + Dependency Set is the set of state elements upon which a goal depends. + +Persistent WMEs are pervasive in Soar, because operators are the main unit of +problem solving. Persistence is necessary for taking any non-monotonic step in a +problem space. However, persistent WMEs also are dependent on WMEs in the +superstate context. The problem in Soar prior to GDS, especially when trying to +create a large-scale system, is that the knowledge developer must always think +about which dependencies can be "ignored" and which may affect the persistent +WME. For example, imagine an exploration robot that makes a persistent decision +to travel to some distant destination based, in part, on its power reserves. Now +suppose that the agent notices that its power reserves have failed. If this +change is not communicated to the state where the travel decision was made, the +agent will continue to act as if its full power reserves were still available. Of course, for this specific example, the knowledge designer can encode some knowledge to react to this inconsistency. The fundamental problem is that the knowledge designer has to consider all possible interactions between all o-supported WMEs and all contexts. Soar systems often use the architecture’s -impasse mechanism to realize a form of decomposition. These potential +impasse mechanism to realize a form of decomposition. These potential interactions mean that the knowledge developer cannot focus on individual problem spaces in isolation when creating knowledge, which makes knowledge development more difficult. Further, in all but the simplest systems, the @@ -1344,29 +1497,27 @@ never co-occur simultaneously. An example might be a driving robot that learned a rule that attempted to match "red light" and "green light" simultaneously. Obviously, for functioning traffic lights, this rule would never fire. By ensuring that local persistent elements are always consistent with the -higher-level context, non-contemporaneous constraints in chunks are *guaranteed* +higher-level context, non-contemporaneous constraints in chunks are _guaranteed_ not to happen. -The GDS captures context dependencies during processing, meaning the architecture will -identify and respond to inconsistencies automatically. The knowledge designer then does -not have to consider potential inconsistencies between local, o-supported WMEs and the -context. +The GDS captures context dependencies during processing, meaning the +architecture will identify and respond to inconsistencies automatically. The +knowledge designer then does not have to consider potential inconsistencies +between local, o-supported WMEs and the context. #### Behavior-level view of the Goal Dependency Set The following discussion covers what the GDS does, and how that impacts production knowledge design and implementation. - - -**Operation of the Goal Dependency Set**: Consider i-support. The persistence of an -i-supported ("instantiation supported") WME depends upon the creating production -instantiation (and, more specifically, the features the instantiation tests). -When one of the conditions in the production instantiation no longer matches, -the instantiation is retracted, resulting in the loss of that support for the -WME. I-support is illustrated in Figure 2.12. A copy of A in the subgoal,As, is -retracted automatically when A changes to A’. The substate WME persists only as -long as it remains justified by A. +**Operation of the Goal Dependency Set**: Consider i-support. The persistence of +an i-supported ("instantiation supported") WME depends upon the creating +production instantiation (and, more specifically, the features the instantiation +tests). When one of the conditions in the production instantiation no longer +matches, the instantiation is retracted, resulting in the loss of that support +for the WME. I-support is illustrated in Figure 2.12. A copy of A in the +subgoal,As, is retracted automatically when A changes to A’. The substate WME +persists only as long as it remains justified by A. In the broadest sense, we can say that some feature `` is "dependent" upon another element `` if `` was used in the creation of ``, i.e., if `` @@ -1376,119 +1527,100 @@ instantiating features. This applies to both i-supported and o- supported WMEs. In Figure 2.12, the change from A to A’ is a dependent change for feature 1 because A was used to create 1. -When A changes, the persistent WME 1 may be no longer consistent with its context -(e.g., A’). The specific solution to this problem through GDS is inspired by the dependency -analysis portion of the justification/chunking algorithm (see [Chapter 4](./04_ProceduralKnowledgeLearning.md)). Whenever an o- -supported WME is created in the local state, the superstate dependencies of that new feature -are determined and added to the goal dependency set (GDS) of that state. Conceptually -speaking, whenever a working memory change occurs, the dependency sets for every state -in the context hierarchy are compared to working memory changes. If a removed element -is found in a GDS, the state is removed from memory (along with all existing substructure). -The dependency set includes only dependencies for o-supported features. For example, in -Figure 2.13, at time $t_0$ , because only i-supported features have been created in the subgoal, -the dependency set is empty. +When A changes, the persistent WME 1 may be no longer consistent with its +context (e.g., A’). The specific solution to this problem through GDS is +inspired by the dependency analysis portion of the justification/chunking +algorithm (see [Chapter 4](./04_ProceduralKnowledgeLearning.md)). Whenever an o- +supported WME is created in the local state, the superstate dependencies of that +new feature are determined and added to the goal dependency set (GDS) of that +state. Conceptually speaking, whenever a working memory change occurs, the +dependency sets for every state in the context hierarchy are compared to working +memory changes. If a removed element is found in a GDS, the state is removed +from memory (along with all existing substructure). The dependency set includes +only dependencies for o-supported features. For example, in Figure 2.13, at time +$t_0$ , because only i-supported features have been created in the subgoal, the +dependency set is empty. ![Simplified Representation of the context dependencies (above the line), local o-supported WMEs (below the line), and the generation of a result. Prior to GDS, this situation led to non-contemporaneous constraints in the chunk that generates 3.](Images/simple-ncc.svg) + /// caption -Simplified Representation of the context dependencies (above the line), local o-supported WMEs (below the line), and the generation of a result. Prior to GDS, this situation led to non-contemporaneous constraints in the chunk that generates 3. +Simplified Representation of the context dependencies (above the line), local +o-supported WMEs (below the line), and the generation of a result. Prior to GDS, +this situation led to non-contemporaneous constraints in the chunk that +generates 3. /// ![The Dependency Set in Soar.](Images/gomor-o-support.svg) + /// caption The Dependency Set in Soar. /// -Three types of features can be tested in the creation of an o-supported feature. Each requires -a slightly different type of update to the dependency set. - -1. **Elements in the superstate**: WMEs in the superstate are added directly to the - goal’s dependency set. In Figure 2.13, the persistent subgoal item 3 is dependent upon - A and D. These superstate WMEs are added to the subgoal’s dependency set when 3 - is added to working memory at time $t_1$. It does not matter that A is i-supported and - Do-supported. -2. **Local i-supported features**: Local i-supported features are not added to the goal - dependency set. Instead, the superstate WMEs that led to the creation of the i- - supported feature are determined and added to the GDS. In the example, when 4 - is created,A, B and C must be added to the dependency set because they are the - superstate features that led to 1 , which in turn led to 2 and finally 4. However, because - item A was previously added to the dependency set at $t_1$ , it is unnecessary to add it - again. -3. **Local o-supported features**: The dependencies of a local o-supported feature have - already been added to the state’s GDS. Thus, tests of local o-supported WMEs do not - require additions to the dependency set. In Figure 2.13, the creation of element 5 does - not change the dependency set because it is dependent only upon persistent items 3 - and 4 , whose features had been previously added to the GDS. - -At any time after t 1 , either the D to D’ or A to A’ transition would cause the removal of -the entire subgoal. TheEtoE’transition causes no retraction becauseEis not in the goal’s -dependency set. +Three types of features can be tested in the creation of an o-supported feature. +Each requires a slightly different type of update to the dependency set. + +1. **Elements in the superstate**: WMEs in the superstate are added directly to + the goal’s dependency set. In Figure 2.13, the persistent subgoal item 3 is + dependent upon A and D. These superstate WMEs are added to the subgoal’s + dependency set when 3 is added to working memory at time $t_1$. It does not + matter that A is i-supported and Do-supported. +2. **Local i-supported features**: Local i-supported features are not added to + the goal dependency set. Instead, the superstate WMEs that led to the creation + of the i- supported feature are determined and added to the GDS. In the example, + when 4 is created,A, B and C must be added to the dependency set because they + are the superstate features that led to 1 , which in turn led to 2 and finally +3. However, because item A was previously added to the dependency set at $t_1$ , + it is unnecessary to add it again. +4. **Local o-supported features**: The dependencies of a local o-supported + feature have already been added to the state’s GDS. Thus, tests of local + o-supported WMEs do not require additions to the dependency set. In Figure 2.13, + the creation of element 5 does not change the dependency set because it is + dependent only upon persistent items 3 and 4 , whose features had been + previously added to the GDS. + +At any time after $t_1$ , either the D to D’ or A to A’ transition would cause the +removal of the entire subgoal. The E to E’ transition causes no retraction +becauseEis not in the goal’s dependency set. **The role of the GDS in agent desig**n: The GDS places some design time constraints on operator implementation. These constraints are: -- Operator actions that are used to remember a previous state/situation should be asserted in the top state. +- Operator actions that are used to remember a previous state/situation should + be asserted in the top state. - All operator elaborations should be i-supported. - Any operator with local actions should be designed to be re-entrant. -Because any dependencies for o-supported subgoal WMEs will be added to the GDS, the -developer must decide if an o-supported element should be represented in a substate or the -top state. This decision is straightforward if the functional role of the persistent element is -considered. Four important capabilities that require persistence are: - -1. **Reasoning hypothetically**: Some structures may need to reflect hypothetical states. - These are "assumptions" because a hypothetical inference cannot always be grounded - in the current context. In problem solvers with truth maintenance, only assumptions - are persistent. -2. **Reasoning non-monotonically**: Sometimes the result of an inference changes one - of the structures on which the inference is dependent. As an example, consider the - task of counting. Each newly counted item replaces the old value of the count. +Because any dependencies for o-supported subgoal WMEs will be added to the GDS, +the developer must decide if an o-supported element should be represented in a +substate or the top state. This decision is straightforward if the functional +role of the persistent element is considered. Four important capabilities that +require persistence are: + +1. **Reasoning hypothetically**: Some structures may need to reflect + hypothetical states. These are "assumptions" because a hypothetical inference + cannot always be grounded in the current context. In problem solvers with truth + maintenance, only assumptions are persistent. +2. **Reasoning non-monotonically**: Sometimes the result of an inference changes + one of the structures on which the inference is dependent. As an example, + consider the task of counting. Each newly counted item replaces the old value of + the count. 3. **Remembering**: Agents oftentimes need to remember an external situation or stimulus, even when that perception is no longer available. -4. **Avoiding Expensive Computations**: In some situations, an agent may have the - information needed to derive some belief in a new world state but the expense of - performing the necessary computation makes this derivation undesirable. For example, - in dynamic, complex domains, determining when to make an expensive calculation is - often formulated as an explicit agent task. - -When remembering or avoiding an expensive computation, the agent/designer is making -a commitment to retain something even though it might not be supported in the current -context. These WMEs should be asserted in the top state. For many Soar systems, especially -those focused on execution in a dynamic environment, most o-supported elements will need -to be stored on the top state. - -For any kind of local, non-monotonic reasoning about the context (counting, projection -planning), features should be stored locally. When a dependent context change occurs, -the GDS interrupts the processing by removing the state. While this may seem like a -severe over-reaction, formal and empirical analysis have suggested that this solution is less -computationally expensive than attempting to identify the specific dependent assumption. - -## Footnotes - -- [1]: In this blocks-world task, the table always has - room for another block, so it is represented as always being "clear". -- [2]: In order to allow these links to have some - substructure, the attribute name may be an identifier, which means that the - attribute may itself have attributes and values, as specified by additional - working memory elements. -- [3]: The original state is the "top" of the stack - because as Soar runs, this state (created first), will be at the top of the - computer screen, and substates will appear on the screen below the top-level - state. -- [4]: Technically, an i-supported WME is only retracted - when it loses instantiation support, not when the creating production is - retracting. For example, a WME could receive i-support from several different - instantiated productions and the retraction of only one would not lead to the - retraction of the WME. justification. If such a result loses i-support from the - justification, it will be retracted if there is no other support. -- [5]: In the past, Soar had various experimental - support mode settings. Since version 9.6, the support mode used is what was - previously called mode 4. with rule syntax (explained in [Chapter - 3](./03_SyntaxOfSoarPrograms.md)) may wish to skip this section and return at a - later point. -- [6]: Robert E. Wray. Ensuring Reasoning Consistency in - Hierarchical Architectures. PhD thesis, University of Michigan, 1998. -- [7]: This subsection will primarily use "state," not - "goal." While these terms are often used nearly-interchangeably in the context - of Soar, states refer to the set of WMEs comprising knowledge related to a - peculiar level of goal. TheGoalDependency Set is the set of state elements upon - which a goal depends. +4. **Avoiding Expensive Computations**: In some situations, an agent may have + the information needed to derive some belief in a new world state but the + expense of performing the necessary computation makes this derivation + undesirable. For example, in dynamic, complex domains, determining when to make + an expensive calculation is often formulated as an explicit agent task. + +When remembering or avoiding an expensive computation, the agent/designer is +making a commitment to retain something even though it might not be supported in +the current context. These WMEs should be asserted in the top state. For many +Soar systems, especially those focused on execution in a dynamic environment, +most o-supported elements will need to be stored on the top state. + +For any kind of local, non-monotonic reasoning about the context (counting, +projection planning), features should be stored locally. When a dependent +context change occurs, the GDS interrupts the processing by removing the state. +While this may seem like a severe over-reaction, formal and empirical analysis +have suggested that this solution is less computationally expensive than +attempting to identify the specific dependent assumption. diff --git a/docs/soar_manual/04_ProceduralKnowledgeLearning.md b/docs/soar_manual/04_ProceduralKnowledgeLearning.md index 5ffc640c..e48b2860 100644 --- a/docs/soar_manual/04_ProceduralKnowledgeLearning.md +++ b/docs/soar_manual/04_ProceduralKnowledgeLearning.md @@ -1,4 +1,5 @@ + # Procedural Knowledge Learning ## Chunking @@ -34,10 +35,10 @@ While chunking is a core capability of Soar, procedural learning is disabled by default. Refer to the following CLI commands for more information about enabling and using chunking: -1. [chunk](../reference/cli/cmd_chunk.md) -1. [trace](../reference/cli/cmd_trace.md) -1. [explain](../reference/cli/cmd_explain.md) -1. [visualize](../reference/cli/cmd_visualize.md) +1. [chunk](../reference/cli/cmd_chunk.md) +2. [trace](../reference/cli/cmd_trace.md) +3. [explain](../reference/cli/cmd_explain.md) +4. [visualize](../reference/cli/cmd_visualize.md) ## Explanation-based Behavior Summarization @@ -54,7 +55,7 @@ are so much more general.
-```Soar title="Soar 9.4.0 chunk" +``` Soar title="Soar 9.4.0 chunk" sp {chunk-94*process-column*apply (state ^operator ^arithmetic-problem @@ -95,7 +96,8 @@ sp {chunk-94*process-column*apply ``` -```Soar hl_lines="4 5 13 14 16 17 19 20 25-35 37" title="Soar 9.6.0 explanation-based chunk" + +``` Soar hl_lines="4 5 13 14 16 17 19 20 25-35 37" title="Soar 9.6.0 explanation-based chunk" sp {chunk-96*process-column*apply (state ^operator ^arithmetic-problem @@ -152,6 +154,7 @@ To remedy this limitation and produce more general chunks, EBBS creates and analyzes a behavior trace. Figure below shows an example behavior trace. ![A close-up of a trace showing differences between a working memory trace (left) and a behavior trace (right). The working memory trace only contains the literal values of the WMEs that matched. The behavior trace, on the other hand, contains variables and various constraints on the values those variables can hold.](Images/chunking-wm-vs-exp-trace.png) + /// caption A close-up of a trace showing differences between a working memory trace (left) and a behavior trace (right). The working memory trace only contains the literal values of the WMEs that matched. The behavior trace, on the other hand, contains variables and various constraints on the values those variables can hold. /// @@ -184,11 +187,13 @@ basis for the behavior trace used for a learning episode. (At this point, the behavior trace is a subgraph of the instantiation graph.) ![A visualization of the behavior trace of a chunk learned by the arithmetic agent. Each box represents a rule that fired in the substate. Arrows show dependencies between rules that create working memory elements and conditions that test those working memory elements.](Images/chunking-trace.png) + /// caption A visualization of the behavior trace of a chunk learned by the arithmetic agent. Each box represents a rule that fired in the substate. Arrows show dependencies between rules that create working memory elements and conditions that test those working memory elements. /// + EBBS also creates an identity graph as it incrementally builds the instantiation graph. Production memory has knowledge about the actual matched value for each element in each condition of a rule in the instantiation graph. Some elements @@ -204,14 +209,14 @@ underlying object and supports identity-based variabilization. **Basic concepts**: - Every condition and action in the instantiation graph has three elements: - - For conditions, the three elements refer to the symbol in the positive - equality test for the identifier, attribute and value of the condition. - For example, the last condition of rule 2 in the - explanation trace figure has `` as - the identifier element, number as the attribute element, and `` as - the value element. - - For actions, the three elements refer to the identifier, attribute and - value of the WME being created. + - For conditions, the three elements refer to the symbol in the positive + equality test for the identifier, attribute and value of the condition. + For example, the last condition of rule 2 in the + explanation trace figure has `` as + the identifier element, number as the attribute element, and `` as + the value element. + - For actions, the three elements refer to the identifier, attribute and + value of the WME being created. - An element is either a variable, like `` or a literal constant, like `23`, `3.3`, or `someString` @@ -220,31 +225,33 @@ underlying object and supports identity-based variabilization. Before we can discuss the algorithm, we must first define one of its central concepts: _identity_. -- **An identity is the set of all variables in a trace that refer to the same - underlying object.** - So we can say that two _variables_ are said to _share - an identity_ if they both refer to the same underlying object. -- **The NULL identity is a special identity that indicates an element which - cannot be generalized and must contain a specific value.** - All elements in - the original rule that reference specific constant values are trivially - assigned the NULL identity. - A variable’s identity can also be _mapped to the - NULL identity_. When this happens, we say the identity has been - **literalized**. +- **An identity is the set of all variables in a trace that refer to the same + underlying object.** - So we can say that two _variables_ are said to _share + an identity_ if they both refer to the same underlying object. +- **The NULL identity is a special identity that indicates an element which + cannot be generalized and must contain a specific value.** - All elements in + the original rule that reference specific constant values are trivially + assigned the NULL identity. - A variable’s identity can also be _mapped to the + NULL identity_. When this happens, we say the identity has been + **literalized**. EBBS traverses a behavior trace of the problem-solving that occurred in the substate to determine which variables in different rule instances refer to the same underlying object. Identities can be shared in the following situations. -1. Variables that have the same name and are in the same rule firing will share - an identity This is the trivial case. The basic semantics of rules implies that - the same variable in a rule references the same underlying object. -2. If a RHS action of one rule creates a WME and a LHS condition of another - rules tests that same WME, then all variables in the condition and actions will - possess the same identity as their counterpart’s corresponding element. The - interaction between the two rules indicates a shared identity between their - corresponding variables. +1. Variables that have the same name and are in the same rule firing will share + an identity This is the trivial case. The basic semantics of rules implies that + the same variable in a rule references the same underlying object. +2. If a RHS action of one rule creates a WME and a LHS condition of another + rules tests that same WME, then all variables in the condition and actions will + possess the same identity as their counterpart’s corresponding element. The + interaction between the two rules indicates a shared identity between their + corresponding variables.

+ ![A behavior trace of two simple rules that matched in a substate.](Images/chunking-trace2.png) + /// caption A behavior trace of two simple rules that matched in a substate. /// @@ -257,6 +264,7 @@ of `` ,`` an `` in rule 1 with the identities of `` ,`` an `` in rule 2. So, the `` in rule 2 shares the same identity as the `` in rule 1. Similarly, the `` in rule 2 shares the same identity as `` in rule 1. In contrast, the `` in rule 2 does NOT share the same identity as the `` in rule + 1. It doesn’t matter that the `` in rule 1 uses the same variable name as @@ -275,18 +283,18 @@ any elements in the final rule that share that identity will not be variablized. When this happens, we say that the identity has been literalized. There are two ways that a rule interaction can effect an identity literalization: -1. If a RHS action of one rule creates a WME element using a constant, literal - value in an element and a LHS condition tests that element, then the - identity of the condition’s variables is literalized and mapped to the NULL - identity. Because the variable in the condition matched a rule that will - always create the same constant, literal value, the condition’s variable - must have that same value. Otherwise, it would not have matched. -2. If a RHS action of one rule creates a WME element using a variable and a LHS - condition tests that that element is a specific value, then the identity of the - action’s variables is literalized and mapped to the NULL identity. Because the - condition requires that the rule that created the matched WME to have a specific - constant, literal value, the action’s variable must have that same value. - Otherwise, it would not have created something that matched the condition. +1. If a RHS action of one rule creates a WME element using a constant, literal + value in an element and a LHS condition tests that element, then the + identity of the condition’s variables is literalized and mapped to the NULL + identity. Because the variable in the condition matched a rule that will + always create the same constant, literal value, the condition’s variable + must have that same value. Otherwise, it would not have matched. +2. If a RHS action of one rule creates a WME element using a variable and a LHS + condition tests that that element is a specific value, then the identity of the + action’s variables is literalized and mapped to the NULL identity. Because the + condition requires that the rule that created the matched WME to have a specific + constant, literal value, the action’s variable must have that same value. + Otherwise, it would not have created something that matched the condition. Identities are the basis of nearly every mechanism in EBBS. DIGU, which is a fairly complicated @@ -296,7 +304,9 @@ shows a trace after identity analysis has been performed. Elements that share an identity in the figure are colored the same.

+ ![A behavior trace incorporating identity analysis.](Images/chunking-trace-identity.png) + /// caption A behavior trace incorporating identity analysis. /// @@ -311,59 +321,61 @@ identity data structure that will be discussed in more detail in Section on the identity graph. + ![Note that the two rows on the bottom indicate when each component occurs during Soar’s processing.](Images/chunking-ebbs-components.png) + /// caption Note that the two rows on the bottom indicate when each component occurs during Soar’s processing. /// ### The Nine Components of Explanation-Based Behavior Summarization -1. **Operator Selection Knowledge Analysis** - This component also occurs before the learning episode. Whenever an operator - is selected, it analyzes what rule firings contributed necessary operator - selection preferences and caches them in all rule instances that tests that - operator. - -2. **Instantiation Creation** - As a rule is fired, copies of the exact knowledge structures that matched - each condition are made. - -3. **Identity Assignment and Propagation** - When a rule matches, identities are created and assigned for each element. - The identity graph built during these rules firings is manipulated later for - further generalization and identity sharing. - -4. **Constraint Tracking** - This component stores every value or relational constraint (e.g. `<> `, - `>= 3.14`, `<< disjunction of constants >>`) placed on variables. - -5. **Collect Full Set of Inferences** - When a rule creates a result with an identifier, children of that identifier - also become results. This step determines which working memory elements - become supergoal results. - -6. **Dependency Analysis** - The first part of a learning episode, this step backtraces through the - behavior trace to determine which rule conditions test working memory - elements in a supergoal. This works similarly in classical chunking. - -7. **Identity Graph Manipulation** - As backtracing occurs, the identity graph is also manipulated to build rules - at the right level of generality and to prevent correctness issues in - previous versions of chunking. - -8. **Constraint Collection** - Constraints recorded during constraint tracking that are encountered during - backtracing are copied to the relevant identities in the identity graph. - Later, during rule formation, these constraints are enforced on identities - included in the learned rule. - -9. **Rule Formation** - The above eight components performed the analysis that EBBS needs to form a - general but correct rule. This final component uses the results of that - analysis to actually build the new rule. This is a complex component that - has eight different stages. If a valid rule is created, Soar immediately - adds the rule to production memory. +1. **Operator Selection Knowledge Analysis** + This component also occurs before the learning episode. Whenever an operator + is selected, it analyzes what rule firings contributed necessary operator + selection preferences and caches them in all rule instances that tests that + operator. + +2. **Instantiation Creation** + As a rule is fired, copies of the exact knowledge structures that matched + each condition are made. + +3. **Identity Assignment and Propagation** + When a rule matches, identities are created and assigned for each element. + The identity graph built during these rules firings is manipulated later for + further generalization and identity sharing. + +4. **Constraint Tracking** + This component stores every value or relational constraint (e.g. `<> `, + `>= 3.14`, `<< disjunction of constants >>`) placed on variables. + +5. **Collect Full Set of Inferences** + When a rule creates a result with an identifier, children of that identifier + also become results. This step determines which working memory elements + become supergoal results. + +6. **Dependency Analysis** + The first part of a learning episode, this step backtraces through the + behavior trace to determine which rule conditions test working memory + elements in a supergoal. This works similarly in classical chunking. + +7. **Identity Graph Manipulation** + As backtracing occurs, the identity graph is also manipulated to build rules + at the right level of generality and to prevent correctness issues in + previous versions of chunking. + +8. **Constraint Collection** + Constraints recorded during constraint tracking that are encountered during + backtracing are copied to the relevant identities in the identity graph. + Later, during rule formation, these constraints are enforced on identities + included in the learned rule. + +9. **Rule Formation** + The above eight components performed the analysis that EBBS needs to form a + general but correct rule. This final component uses the results of that + analysis to actually build the new rule. This is a complex component that + has eight different stages. If a valid rule is created, Soar immediately + adds the rule to production memory. The following sections will describe each component in more detail. @@ -392,16 +404,16 @@ should not be included in any chunks produced from that substate. In practice, however, it may make sense to design an agent so that search control does affect the correctness of search. Here are just two examples: -1. Some of the tests for correctness of a result are included in productions - that prefer operators that will produce correct results. The system will work - correctly only when those productions are loaded. +1. Some of the tests for correctness of a result are included in productions + that prefer operators that will produce correct results. The system will work + correctly only when those productions are loaded. -2. An operator is given a worst preference, indicating that it should be used - only when all other options have been exhausted. Because of the semantics of - worst, this operator will be selected after all other operators; however, if - this operator then produces a result that is dependent on the operator - occurring after all others, this fact will not be captured in the conditions - of the chunk. +2. An operator is given a worst preference, indicating that it should be used + only when all other options have been exhausted. Because of the semantics of + worst, this operator will be selected after all other operators; however, if + this operator then produces a result that is dependent on the operator + occurring after all others, this fact will not be captured in the conditions + of the chunk. In both of these cases, part of the test for producing a result is implicit in search control productions. This move allows the explicit state test to be @@ -487,38 +499,38 @@ created and propagated using the following rules: 1. If the same variable appears in multiple places in the same rule, it must be assigned the same identity. -1. The NULL Identity is assigned to any element with a literal value in the +2. The NULL Identity is assigned to any element with a literal value in the original rule. -1. A new identity is created and assigned for: - - All right-hand side action elements that produce a new Soar identifier in - the substate These are also known as unbound RHS variables. - - All variable elements of conditions that matched superstate WMEs It is - important to note that if two conditions both match the same superstate - WME, each condition is considered independent. This means that each - condition is assigned new identities for each of its elements and will - produce its own condition in the final learned rule. This is a key way - that EBBS differs from previous versions of chunking. -1. An existing identity is propagated for: - 1. Any condition element that matched a substate WME with existing identities - Each element is assigned the identity found in the corresponding element - of the action of the rule that created that WME. This propagates - identities forward through the behavior trace, which allows us to - represent that the variable in the condition refers to the same object - as the variable in the action of the other rule. - 1. Any element that matches special working memory elements called singletons - are assigned the same identity. Singletons are working memory elements - that are guaranteed to only have a single possible value in a state. The - most important singleton is the local `^superstate` singleton, which is - an architecturally created WME that links the substate to the - superstate, for example `(S2 ^superstate S1)`. Since we know that it’s - impossible for there to be two superstate features in a state, all - conditions that test that singleton WME will be assigned the same - identities. While there are a variety of built-in singletons for - architecturally-created WMEs, users can also specify their own - domain-specific singletons to eliminate unnecessary generality when - learning. The full list of architecturally-created singletons can be - found in the [`chunk` command’s](../reference/cli/cmd_chunk.md) help - entry. +3. A new identity is created and assigned for: + - All right-hand side action elements that produce a new Soar identifier in + the substate These are also known as unbound RHS variables. + - All variable elements of conditions that matched superstate WMEs It is + important to note that if two conditions both match the same superstate + WME, each condition is considered independent. This means that each + condition is assigned new identities for each of its elements and will + produce its own condition in the final learned rule. This is a key way + that EBBS differs from previous versions of chunking. +4. An existing identity is propagated for: + 1. Any condition element that matched a substate WME with existing identities + Each element is assigned the identity found in the corresponding element + of the action of the rule that created that WME. This propagates + identities forward through the behavior trace, which allows us to + represent that the variable in the condition refers to the same object + as the variable in the action of the other rule. + 2. Any element that matches special working memory elements called singletons + are assigned the same identity. Singletons are working memory elements + that are guaranteed to only have a single possible value in a state. The + most important singleton is the local `^superstate` singleton, which is + an architecturally created WME that links the substate to the + superstate, for example `(S2 ^superstate S1)`. Since we know that it’s + impossible for there to be two superstate features in a state, all + conditions that test that singleton WME will be assigned the same + identities. While there are a variety of built-in singletons for + architecturally-created WMEs, users can also specify their own + domain-specific singletons to eliminate unnecessary generality when + learning. The full list of architecturally-created singletons can be + found in the [`chunk` command’s](../reference/cli/cmd_chunk.md) help + entry. Note that rule 1 may conflict with other rules. For example, if a variable appears in two different conditions, then two different identities may propagate @@ -652,19 +664,19 @@ identities and a single directed join edge that initially points back to itself. As the agent backtraces through the instantiation graph, EBBS will manipulate the identity graph based on the condition-action pairs it encounters. -1. **Joining identities** - If a condition matches an action with a conflicting identity, EBBS performs a - join operation between the two identities. This chooses one identity as - the joined identity and points the join edges of the other identity and any - previously joined identities to the new joined identity. Note that any time - EBBS uses an element’s identity, it is actually using the joined identity. -2. **Literalizing identities** - If a condition/action with a variable element matches an action/condition - with a literal element, EBBS marks the identity as literalized. This means - that any conditions in the final chunk that have elements with that identity - will be considered to have the NULL identity, just like constants, and will - not be variablized. Instead, the matched value will be used for that - element. +1. **Joining identities** + If a condition matches an action with a conflicting identity, EBBS performs a + join operation between the two identities. This chooses one identity as + the joined identity and points the join edges of the other identity and any + previously joined identities to the new joined identity. Note that any time + EBBS uses an element’s identity, it is actually using the joined identity. +2. **Literalizing identities** + If a condition/action with a variable element matches an action/condition + with a literal element, EBBS marks the identity as literalized. This means + that any conditions in the final chunk that have elements with that identity + will be considered to have the NULL identity, just like constants, and will + not be variablized. Instead, the matched value will be used for that + element. #### Constraint Collection @@ -673,27 +685,27 @@ the superstate, but could transitively place constraints on the values of variab in conditions that \textit{will} appear in a chunk. To handle this, once backtracing is complete, EBBS: -- stores constraints on the value a single identity, for example `>=0`, `<23`. -- stores relational constraints between two identities, for example `> `, - `< ` or `<> `. -- stores all of these constraints based on the underlying identities, not - the variables used. For example, if a variable `` had the constraint - `<> `, EBBS would record that the variables that share the identity of - `` cannot have the same value as variables that share the identity of - ``. +- stores constraints on the value a single identity, for example `>=0`, `<23`. +- stores relational constraints between two identities, for example `> `, + `< ` or `<> `. +- stores all of these constraints based on the underlying identities, not + the variables used. For example, if a variable `` had the constraint + `<> `, EBBS would record that the variables that share the identity of + `` cannot have the same value as variables that share the identity of + ``. ### Rule Formation There are eight distinct, sequential stages to rule formation: -1. Conditions and Action Generation -2. Constraint Enforcement -3. Identity-based Generalization -4. Condition Merging -5. Condition Simplification -6. Rule Repair and Validation -7. Condition Re-Ordering -8. Add and Recursively Learn Additional Rules +1. Conditions and Action Generation +2. Constraint Enforcement +3. Identity-based Generalization +4. Condition Merging +5. Condition Simplification +6. Rule Repair and Validation +7. Condition Re-Ordering +8. Add and Recursively Learn Additional Rules The following sections will give a brief overview of each stage. @@ -754,20 +766,20 @@ EBBS polishes the conditions of the learned rule by pruning unnecessary constraints on literalized elements and replacing multiple disjunction constraints with a single simplified disjunction. -1. Merging disjunctions: If an element in a condition has two disjunction - tests, the constraints will be merged into a single disjunction that - contains only the shared values. `{ << a b c >> << b c d >> }` becomes `{ -<> }`, because it is impossible fo `` to be either a or b. This - will also eliminate any duplicate disjunctions. -2. Throwing out unnecessary constraints: If an element in a condition has been - literalized but also has a literal constraint on its value, then the - constraint is unnecessary and will be thrown out. For example, ` ^value{ < -33 23 }` becomes ` ^value 23`. +1. Merging disjunctions: If an element in a condition has two disjunction + tests, the constraints will be merged into a single disjunction that + contains only the shared values. `{ << a b c >> << b c d >> }` becomes `{ + <> }`, because it is impossible fo `` to be either a or b. This + will also eliminate any duplicate disjunctions. +2. Throwing out unnecessary constraints: If an element in a condition has been + literalized but also has a literal constraint on its value, then the + constraint is unnecessary and will be thrown out. For example, ` ^value{ < + 33 23 }` becomes ` ^value 23`. #### Rule Validation and Repair At this point, the rule is essentially formed. Chunking must now make sure that -the learned rule can be legally added to production memory. Specifically, the +the learned rule can be legally added to production memory. Specifically, the rule cannot have any conditions or actions that are not linked to a goal state specified in the rule. @@ -839,6 +851,7 @@ can even print justifications out like other rules. The only differences between chunks and justifications are: ???+ info + Even though justifications don’t contain variables, justifications can be over-general because they don’t incorporate enough knowledge, for example, operator selection knowledge. @@ -847,6 +860,7 @@ chunks and justifications are: that matched. Justifications contain no variables. ???+ info + Justifications can have variables in the negated conditions and negated conjunctions of conditions. They just don’t have any variables in its positive conditions. @@ -962,7 +976,7 @@ that working memory is located is and how it should be referenced in the learned rule, because the problem solving referenced the result relative to the local substate. -As described in [validating rule and repairing unconnected conditions](#validating-rule-and-repairing-unconnected-conditions), +As described in [Rule Validation and Repair](#rule-validation-and-repair), EBBS repairs the rule by adding new grounding conditions that provide a link from a state, which is tested somewhere else in the rule, to the unconnected condition or action. It does this by searching @@ -1000,7 +1014,7 @@ specific chunk was repaired by looking at the chunk’s individual stats If an agent uses rules that create operator preferences to choose amongst multiple operators in the substate, it is possible that the reasoning behind those rules needs to be incorporated in any rule learned. This topic is -discussed in greater detail in [ROSK tracking](#relevant-operator-selection-knowledge-tracking). +discussed in greater detail in [ROSK tracking](#operator-selection-knowledge-analysis). EBBS will incorporate relevant operator selection knowledge if you enable the [chunk setting add-osk](../reference/cli/cmd_chunk.md), which is off by default. @@ -1112,35 +1126,35 @@ the number of rules that repeatedly created that WME. Generalizing problem-solving based on knowledge recalled from an external memory system can be problematic for three main reasons. -1. **Knowledge can change after the learning episode** - Semantic knowledge can be modified by the agent. Different semantic - knowledge can effect different problem-solving, in which case a rule based on - the original problem-solving would be incorrect. -2. **Justification for a memory recall is opaque to agent** - EBBS does not have access - to the reasoning behind why a piece of knowledge was recalled from a memory - system. For example, consider the case of a semantic memory that is recalled - because it has the highest level of activation at a particular time. In a future - situation, the same semantic memory may not be the most active, in which case - something else would be recalled and different problem-solving could occur. - Because of that possibility, the original rule is not guaranteed to produce the - same result and hence has the potential to be incorrect. (Note that this can - also occur with episodic memory queries.) -3. **Knowledge from semantic or episodic memory recalled directly into the - substate is considered local** - To understand why this is a problem, remember that a chunk’s conditions are - based on the conditions in the behavior trace that tested knowledge linked - to a superstate. (See [operational analysis](#operationality-analysis) - for more information.) If semantic or - episodic memory is recalled directly into the substate, then any conditions - that test that recalled knowledge is considered local to the substate and - will not be included as a condition in the chunk. So, even though the - substate reasoning required some piece of semantic knowledge to exist, the - chunk will not require it. And, since the learned rule is not incorporating - some of the reasoning and constraints that involved the recalled knowledge, - the rule may be over-general. To avoid this situation, an agent can retrieve - the knowledge in a higher-level state rather than the substate in which the - rule is learned. +1. **Knowledge can change after the learning episode** + Semantic knowledge can be modified by the agent. Different semantic + knowledge can effect different problem-solving, in which case a rule based on + the original problem-solving would be incorrect. +2. **Justification for a memory recall is opaque to agent** + EBBS does not have access + to the reasoning behind why a piece of knowledge was recalled from a memory + system. For example, consider the case of a semantic memory that is recalled + because it has the highest level of activation at a particular time. In a future + situation, the same semantic memory may not be the most active, in which case + something else would be recalled and different problem-solving could occur. + Because of that possibility, the original rule is not guaranteed to produce the + same result and hence has the potential to be incorrect. (Note that this can + also occur with episodic memory queries.) +3. **Knowledge from semantic or episodic memory recalled directly into the + substate is considered local** + To understand why this is a problem, remember that a chunk’s conditions are + based on the conditions in the behavior trace that tested knowledge linked + to a superstate. (See [Dependency Analysis](#dependency-analysis) + for more information.) If semantic or + episodic memory is recalled directly into the substate, then any conditions + that test that recalled knowledge is considered local to the substate and + will not be included as a condition in the chunk. So, even though the + substate reasoning required some piece of semantic knowledge to exist, the + chunk will not require it. And, since the learned rule is not incorporating + some of the reasoning and constraints that involved the recalled knowledge, + the rule may be over-general. To avoid this situation, an agent can retrieve + the knowledge in a higher-level state rather than the substate in which the + rule is learned. ### Learning from Instruction @@ -1175,7 +1189,7 @@ recalled instructions. The following outline describes the logic that happens at each step. For a more detailed description of the [various filters](02_TheSoarArchitecture.md#how-preferences-are-evaluated-to-decide-an-operator) -(but not the ROSK). Note that depending on the set of preferences being +(but not the ROSK). Note that depending on the set of preferences being processed, impasses may occur at some of these stages, in which case, no operator is selected and the ROSK is emptied. Moreover, if the candidate set is reduced to zero or one, the decision process will exit with a finalized ROSK. @@ -1207,16 +1221,15 @@ the decision process continues. - **Indifferent/Numeric Filter** This is the final stage, so the operator is now selected based on the agent’s exploration policy. How indifferent preferences are added to the ROSK depends on whether any numeric indifferent preferences exist. - - 1. If there exists at least one numeric indifferent preference, then every - numeric preference for the winning candidate is added to the ROSK. There - can be multiple such preferences. Moreover, all binary indifferent - preferences between that winning candidate and candidates without a - numeric preference are added. - 2. If all indifferent preferences are non-numeric, then any unary indifferent - preferences for the winning candidate are added to the ROSK. Moreover, all - binary indifferent preferences between that winning candidate and other - candidates are added. + 1. If there exists at least one numeric indifferent preference, then every + numeric preference for the winning candidate is added to the ROSK. There + can be multiple such preferences. Moreover, all binary indifferent + preferences between that winning candidate and candidates without a + numeric preference are added. + 2. If all indifferent preferences are non-numeric, then any unary indifferent + preferences for the winning candidate are added to the ROSK. Moreover, all + binary indifferent preferences between that winning candidate and other + candidates are added. The logic behind adding binary indifferent preferences between the selected operator and the other final candidates is that those binary indifferent @@ -1279,60 +1292,60 @@ correct. Soar learns a chunk every time a subgoal produces a result, unless one of the following conditions is true: -1. Chunking is off - This corresponds to the [command chunk never](../reference/cli/cmd_chunk.md). -2. Chunking was only enabled for some states, and the subgoal in question is not - one of them When chunking is enabled via the only or except command, the agent - must specify which states learning either occurs in or doesn’t occur in, - respectively. For the except setting, Soar will learn rules in all states in - which a `dont-learn` RHS production action was not executed. Similarly, for the - only setting, Soar will learn rules in all states where a `force-learn` RHS - production action was executed, cf. [Controlling chunking](03_SyntaxOfSoarPrograms.md#controlling-chunking) - for more information. This capability is provided for debugging and - practical system development, but it is not part of the theory of Soar. -3. The chunk learned is a duplicate of another production or chunk already in - production memory In some rare cases, a duplicate production will not be - detected because the order of the conditions or actions is not the same as an - existing production. -4. The problem-solving in the substate violated one of the enabled correctness - guarantee filters During the development of explanation-based behavior summarization, we have - developed a list of possible causes of incorrect chunks. EBBS’s correctness - guarantee filters detect when those situations occur and prevents a chunk from - being learned. For example, the allow-local-negations filter will prevent a rule - from being formed if the problem-solving that led to the result was - dependent on a condition that tested whether a subgoal WME doesn’t exist. - Since there is no practical way to determine why a piece of knowledge - doesn’t exist, testing a local negation can result in an over-general and - incorrect chunk, cf. [prohibiting known sources for correctness issues](../reference/cli/cmd_chunk.md#preventing-possible-correctness-issues) - for more information. Note that correctness filters have not yet been - implemented for all the identified potential sources of correctness issues. -5. The chunking option bottom-only is on and a chunk was already built in the - bottom subgoal that generated the results With bottom-only chunking, chunks are - learned only in states in which no subgoal has yet generated a chunk. In this - mode, chunks are learned only for the "bottom" of the subgoal hierarchy and not - the intermediate levels. With experience, the subgoals at the bottom will be - replaced by the chunks, allowing higher level subgoals to be chunked. See - [chunk reference](../reference/cli/cmd_chunk.md) for details of chunk used - with the bottom-only setting. -6. The problem-solving that led to the result contained a condition that tested - the architecturally-created ` ^quiescence t` augmentation This mechanism - is motivated by the chunking from exhaustion problem, where the results of a - subgoal are dependent on the exhaustion of alternatives - (see [Problem-Solving that does not test the superstate](04_ProceduralKnowledgeLearning.md#problem-solving-that-doesnt-test-the-superstate)). - If this substate augmentation is encountered when determining the - conditions of a chunk, then no chunk will be built for the currently considered - action. This is recursive, so that if an un-chunked result is relevant to a - second result, no chunk will be built for the second result. This does not - prevent the creation of a chunk that would include^quiescence tas a condition. -7. The problem-solving in the substate did not test any knowledge in the - superstate In these cases, the chunk learned does not have any conditions - and is not a legal production. Note that this creates an unusual persistence - issue for any results that came out of the substate. Since a justification - or chunk was not learned, there is no rule in the superstate that can - provide either i-support or o-support for the result that came out of the - substate. Consequently, those result WMEs will be completely dependent on - the rules that fired within the substate. So, when the substate is removed, - those results will also be removed. +1. Chunking is off + This corresponds to the [command chunk never](../reference/cli/cmd_chunk.md). +2. Chunking was only enabled for some states, and the subgoal in question is not + one of them When chunking is enabled via the only or except command, the agent + must specify which states learning either occurs in or doesn’t occur in, + respectively. For the except setting, Soar will learn rules in all states in + which a `dont-learn` RHS production action was not executed. Similarly, for the + only setting, Soar will learn rules in all states where a `force-learn` RHS + production action was executed, cf. [Controlling chunking](03_SyntaxOfSoarPrograms.md#controlling-chunking) + for more information. This capability is provided for debugging and + practical system development, but it is not part of the theory of Soar. +3. The chunk learned is a duplicate of another production or chunk already in + production memory In some rare cases, a duplicate production will not be + detected because the order of the conditions or actions is not the same as an + existing production. +4. The problem-solving in the substate violated one of the enabled correctness + guarantee filters During the development of explanation-based behavior summarization, we have + developed a list of possible causes of incorrect chunks. EBBS’s correctness + guarantee filters detect when those situations occur and prevents a chunk from + being learned. For example, the allow-local-negations filter will prevent a rule + from being formed if the problem-solving that led to the result was + dependent on a condition that tested whether a subgoal WME doesn’t exist. + Since there is no practical way to determine why a piece of knowledge + doesn’t exist, testing a local negation can result in an over-general and + incorrect chunk, cf. [prohibiting known sources for correctness issues](../reference/cli/cmd_chunk.md#preventing-possible-correctness-issues) + for more information. Note that correctness filters have not yet been + implemented for all the identified potential sources of correctness issues. +5. The chunking option bottom-only is on and a chunk was already built in the + bottom subgoal that generated the results With bottom-only chunking, chunks are + learned only in states in which no subgoal has yet generated a chunk. In this + mode, chunks are learned only for the "bottom" of the subgoal hierarchy and not + the intermediate levels. With experience, the subgoals at the bottom will be + replaced by the chunks, allowing higher level subgoals to be chunked. See + [chunk reference](../reference/cli/cmd_chunk.md) for details of chunk used + with the bottom-only setting. +6. The problem-solving that led to the result contained a condition that tested + the architecturally-created ` ^quiescence t` augmentation This mechanism + is motivated by the chunking from exhaustion problem, where the results of a + subgoal are dependent on the exhaustion of alternatives + (see [Problem-Solving that does not test the superstate](04_ProceduralKnowledgeLearning.md#problem-solving-that-doesnt-test-the-superstate)). + If this substate augmentation is encountered when determining the + conditions of a chunk, then no chunk will be built for the currently considered + action. This is recursive, so that if an un-chunked result is relevant to a + second result, no chunk will be built for the second result. This does not + prevent the creation of a chunk that would include^quiescence tas a condition. +7. The problem-solving in the substate did not test any knowledge in the + superstate In these cases, the chunk learned does not have any conditions + and is not a legal production. Note that this creates an unusual persistence + issue for any results that came out of the substate. Since a justification + or chunk was not learned, there is no rule in the superstate that can + provide either i-support or o-support for the result that came out of the + substate. Consequently, those result WMEs will be completely dependent on + the rules that fired within the substate. So, when the substate is removed, + those results will also be removed. ## Usage @@ -1343,22 +1356,22 @@ More details on the `chunk` command and its settings can be found in the By default, chunking is off. -- To turn on chunking: `chunk always` -- To turn off chunking: `chunk never` +- To turn on chunking: `chunk always` +- To turn off chunking: `chunk never` In real world agents, there may be certain problem spaces in which you don't want your agent to learn rules. Chunking has a mechanism to allow agents to dynamically specify the states in which rules are learned. - To turn off chunking in all states except ones manually flagged on: - - Use `chunk only` setting. - - Design an agent rule that executes the RHS action `force-learn`, - which only matches in states in which you want to learn rules. + - Use `chunk only` setting. + - Design an agent rule that executes the RHS action `force-learn`, + which only matches in states in which you want to learn rules. - To turn on chunking in all states except ones manually flagged off: - - Use `chunk except` setting. - - Design an agent rule that executes the RHS action `dont-learn`, - which only matches in states in which you don't want to learn - rules. + - Use `chunk except` setting. + - Design an agent rule that executes the RHS action `dont-learn`, + which only matches in states in which you don't want to learn + rules. Depending on your agent design, you may want to consider enabling the `add-osk` option. As of Soar 9.6.0, EBBS does not incorporate operator @@ -1423,29 +1436,29 @@ information about the chunk singleton command. **Printing Rules:** -- To print all chunks learned: - `print --chunks` or `print -c` -- To print all justifications learned (and still matching): - `print --justifications` or `print -j` -- To print a rule or justification: - `print ` +- To print all chunks learned: + `print --chunks` or `print -c` +- To print all justifications learned (and still matching): + `print --justifications` or `print -j` +- To print a rule or justification: + `print ` For more information on print, see the [print command reference](../reference/cli/cmd_print.md). **Trace Messages:** -- To print when new rules are learned (just the name): - `trace --learning 1` or `trace -l 1` -- To print when new rules are learned (the full rule): - `trace --learning 2` or `trace -l 2` -- To print a trace of the conditions as they are collected during - backtracing: - `trace --backtracing` or `trace -b` -- To print warnings about chunking issues detected while learning: - `trace --chunk-warnings` or `trace -C` -- To print when learned chunks match and fire: - `trace --backtracing` or `trace -b` +- To print when new rules are learned (just the name): + `trace --learning 1` or `trace -l 1` +- To print when new rules are learned (the full rule): + `trace --learning 2` or `trace -l 2` +- To print a trace of the conditions as they are collected during + backtracing: + `trace --backtracing` or `trace -b` +- To print warnings about chunking issues detected while learning: + `trace --chunk-warnings` or `trace -C` +- To print when learned chunks match and fire: + `trace --backtracing` or `trace -b` For more information on trace, see the [trace command reference](../reference/cli/cmd_trace.md). @@ -1461,7 +1474,7 @@ Chunking automatically compiles various statistics about the procedural rule learning that an agent performs. To access these stats, use the command `chunk stats` or `stats -l` -```text +``` text =========================================================================== Explanation-Based Chunking Statistics =========================================================================== @@ -1516,12 +1529,12 @@ using the explain mechanism as described in the #### Interrupting Execution To Examine Learning -- To stop Soar after each successful learning episode: - `chunk interrupt on` -- To stop Soar after detecting any learning issue: - `chunk warning-interrupt on` -- To stop Soar after learning a rule that the explainer recorded: - `chunk explain-interrupt on` +- To stop Soar after each successful learning episode: + `chunk interrupt on` +- To stop Soar after detecting any learning issue: + `chunk warning-interrupt on` +- To stop Soar after learning a rule that the explainer recorded: + `chunk explain-interrupt on` For more information about how to record when a specific rule is learned, see the [explain command reference](../reference/cli/cmd_explain.md) that @@ -1575,7 +1588,7 @@ output, i.e. the chunk being discussed. Tip: This is a good way to get a chunk id so that you don't have to type or paste in a chunk name. -```text +``` text ======================================================= Explainer Summary ======================================================= @@ -1608,7 +1621,7 @@ explanation trace you want to explore. Tip: Use the alias `c` to quickly start discussing a chunk, for example: -```soar +``` soar soar % c 3 Now explaining chunk*apply*move-gripper-above*pass*top-state*OpNoChange*t6-1. - Note that future explain commands are now relative @@ -1642,9 +1655,9 @@ sp {chunk*apply*move-gripper-above*pass*top-state*OpNoChange*t6-1 **`explain formation`** -Once you specify a rule to explain, this will be one of the first commands you issue. `explain formation` provides an explanation of the initial rule that fired which created a result. This is what is called the `base instantiation' and is what led to the chunk being learned. Other rules may also be base instantiations if they previously created children of the base instantiation's results. They also will be listed in the initial formation output. +Once you specify a rule to explain, this will be one of the first commands you issue. `explain formation` provides an explanation of the initial rule that fired which created a result. This is what is called the `base instantiation' and is what led to the chunk being learned. Other rules may also be base instantiations if they previously created children of the base instantiation's results. They also will be listed in the initial formation output. -```soar +``` soar soar % explain formation ------------------------------------------------------------------------------------ The formation of chunk 'chunk*apply*move-gripper-above*pass*top-state*OpNoChange*t6-1' (c 1) @@ -1690,7 +1703,7 @@ explainer. Tip: Use the alias `i ` to quickly view an instantiation, for example: -```text +``` text soar % i 30 Explanation trace of instantiation # 30 (match of rule pick-up*propose*move-gripper-above at level 3) - Shortest path to a result: i 30 -> i 31 @@ -1725,7 +1738,7 @@ commands. Tip: Use the aliases `et` and `wt` to quickly switch between traces. -```text +``` text soar % explain w Working memory trace of instantiation # 30 (match of rule pick-up*propose*move-gripper-above at level 3) 1: (S9 ^name pick-up) No i 28 (elaborate*state*operator*name) @@ -1767,7 +1780,7 @@ By default, only identity sets that appear in the chunk will be displayed in the identity analysis. To see the identity set mappings for other sets, change the `only-chunk-identities` setting to `off`. -```text +``` text soar % explain identity ========================================================================= - Variablization Identity to Identity Set Mappings - @@ -1813,7 +1826,7 @@ Explain's `stat` command prints statistics about the specific chunk being discussed. This is a good way to see whether any generality or correctness issues were detected while learning that rule. -```text +``` text =========================================================== Statistics for 'chunk*apply*move-gripper-above*pass*top-state*OpNoChange*t6-1' (c 1): =========================================================== @@ -1850,6 +1863,7 @@ either Soar exits or a `soar init` is executed. This option is still considered experimental and in beta. ![A colored visualization of a behavior trace](Images/chunking-trace-identity.png) + /// caption A colored visualization of a behavior trace /// diff --git a/docs/soar_manual/Images/rl-optrace.fig b/docs/soar_manual/Images/rl-optrace.fig index 5c54258d..c4b1e3ad 100644 --- a/docs/soar_manual/Images/rl-optrace.fig +++ b/docs/soar_manual/Images/rl-optrace.fig @@ -2,7 +2,7 @@ Landscape Center Inches -Letter +Letter 100.00 Single -2 diff --git a/docs/soar_manual/Images/smem-concept.svg b/docs/soar_manual/Images/smem-concept.svg index 5898468c..7ef274d5 100644 --- a/docs/soar_manual/Images/smem-concept.svg +++ b/docs/soar_manual/Images/smem-concept.svg @@ -7,7 +7,7 @@ viewBox="0.00 0.00 301.00 149.80" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> -