The Soar less (than) Frequently Asked Questions List: Appendum to Soar FAQ

Last updated March 2000

Frank Ritter

Marios Avraamides


Table of Contents

Section 0: Introduction

Section 1: General Resources

Section 2: More on Soar

Section 3: Advanced Programming Tips

Section 0: Introduction

This is the introduction to the appendum to the Soar FAQ.

In the appendum, we put stuff that doesn't belong in the FAQ itself. These answers are either too specialized, or too transitory, or not yet frequent. Right now it's a bit of a hodge-podge, dog's breakfast sort-of-thing, but there are some useful items, and serves as a repository until a proper casebook it built. We also have started to save some reusable mail from the soar-bugs mailing list.

Suggestions for new questions, answers, re-phrasing, deletions and so on, are all welcomed. Please include the word "FAQ" in the subject of your e-mail. Please use the mailing lists noted below for general questions, but if they fail or you do not know which one to use, contact one of us.

Frank E. Ritter (

Gordon D. Baxter ( or ( 

Back to Table of Contents

Section 1: General Resources

(G1) Burl: A general learning mechanism

It answers the question: How do I do psychologically plausible lookahead search in Soar?

Burl is a general learning mechanism for using bottom-up recognition learning as a way to build expertise written by Todd Johnson. A description of it is available from .

Code is available from Todd at

(G2) A comparison between Soar and ActR

Todd Johnson has written a paper laying out the theoretical distinctions in Act-R and Soar and then compares control in Act-R and Soar from a cognitive perspective. The paper looks at how each architecture fares with respect to relevant behavioral phenomena.

Todd intends to expand this paper into a general comparison of Act-R and Soar for the cognitive science community. To this end, he would appreciate your comments on the present version. A web-based version is available at

Johnson, T. R. (1996). Control in Act-R and Soar, Proceedings of the First European Workshop on Cognitive Modeling (pp. 201-208): Technische Universitat Berlin.

A revised version appeared in the Proceedings of the 1997 Cognitive Science conference

Gary Jones has written up a comparison between Soar and ActR. The long version is available on the web in the ONREUR Newsletter, and a more condensed version was published in AISBQ: Jones G. (1996). The architectures of Soar and ACT-R, and how they model human behaviour. Artificial Intelligence and Simulation of Behaviour Quarterly, Winter 1996, 96, 41-44.

Back to Table of Contents

(G3) A general model of teamwork

As you may well know, the Soar/IFOR-CFOR project has been developing agents for complex multi-agent domains, specifically distributed interactive simulation (DIS) environments.  As part of this effort at ISI, we have been developing a general model of teamwork, to facilitate agents' coherent teamwork in complex domains. This model, called STEAM, at present involves about 250 productions. We have used this model in developing three separate types of agent teams (including one outside of DIS environments). Since this model may be of use to some of you working with multi-agent Soar systems, we are now making it available to the Soar group.

Here is a pointer to the relevant web page describing STEAM:

Documentation for the model is available on the web page; however, if there are additional questions, I will be happy to answer them. Any feedback on this topic is very welcome.

 Milind Tambe (Thu, 6 Mar 1997 18:27:30 PST)

Information Sciences Institute & Computer science department

University of Southern California


fax:310-822-0751 4676

Admiralty Way

Marina del Rey, CA 90292

Back to Table of Contents

(G4) A model that does reflection

From: Ellen Jane Bass []

Subject: reflection and deduction code


Date: Wed, 20 Sep 1995 17:02:09 -0400 (EDT)

For grabs ---   My reflection model is written in Soar 6.2.5 nnpscm. I have created a version of it that does not require the Nottingham environment.  It starts up after the ATC task has been performed and the aircraft has disappeared from the display.   Although it is being updated based on comments from the Soar Workshop, the current version of the code should be available by anonymous FTP from   Go to the directory ~ftp/chmsr/ellen/reflect. If that does not get you to the directory, try the whole path name /home/newisye/ftp/chmsr/ellen/reflect   The file README-reflect-after-run tells you what to load. Basically you need to load   chunks-after-task.soar deduction.soar known-symbols.soar memory.soar reflect-after-run.soar reflect.soar select-runway.soar   Let me know if you need help.

Comments on the code and/or the comments appreciated.   Ellen Bass Center for Human-Machine Systems Research work : (404) 894-4318 School of Industrial and Systems Engineering fax  : (404) 894-2301 Georgia Institute of Technology home : (404) 378-4918 765 Ferst Drive Atlanta, GA 30332-0205

Back to Table of Contents

(G5) A model that does concept/category acquisition

Symbolic Concept Acquisition (SCA), versions 1 and 2, including variants.

Back to Table of Contents

(G6) Unofficial mirror

The Soar FAQ is also mirrored (unofficially) at Michigan by Seth Rogers ( as This may be more convenient for those users not located in England or Europe.

Back to Table of Contents

(G7) Soar and Linux

[Forwarded by Thomas Head [] Fri, 13 Jun 1997 13:39:53 -0400]

SAL (Scientific Applications on Linux, http://SAL.KachinaTech.COM) has an entry of your software Soar at

http://SAL.KachinaTech.COM/Z/3/S OAR.html

Before the official release in June, we send this message to all software developers in SAL database to acquire any necessary update.

We would like our page of your software offers accurate and up-to-date information to the Linux/Unix community. Hence we made a template page (http://SAL.KachinaTech.COM/.template.html) which hopefully would help you understand the terminology used in the SAL pages. If there is no addition/modification needed in the page of your software, you could simply do nothing. If your software are among those recently added items in SAL, we encourage you to have a look of the page of your software and then let us know any changes needed. For example: Is the description covers most keywords associated with the software? (since many SAL users take advantages of SAL's search engine) How about adding some Screen Shot images or a Logo/Icon image? Please look at http://SAL.KachinaTech.COM/.template.html for more detail.

SAL belongs to all Linux/Unix users, and we hope it will make some contribution to encourage people to use/port software on Linux/Unix platforms. We certainly appreciate you made your software available to Linux community.

SAL Team http://SAL.KachinaTech.COM

Back to Table of Contents

(G8) Multiple runs of Soar

How can I run Soar many times without user intervention (i.e., in a batch mode).

Answer: Bob Wray has put a page on the WWW describing how he ran Soar in a batch mode to collect data for his thesis. The site includes examples of csh scripts, tcl scripts, and Soar code he used in the process:

Back to Table of Contents

(G9) Soar memorabilia

Soar on Headline News

Since the ISI group hasn't mentioned it yet, I'd like to point out that Soar made CNN Headline News on 26 Aug 1997 with reports about Steve and RWA-Soar.

You can view the story on the CNN website at

From: "Paul E. Nielsen" []


A top 10 list

Here's a heretofore unrevealed top ten list I [Bob Doorenbos] wrote back in June '93 when, shortly before a Soar workshop, Rick Lewis asked people to send him their "concerns about Soar" -- issues, problems, worries, etc. that he would try to summarize during the workshop. I sent him the following list. For some strange reason, Rick failed to address any of these. BTW, today is Rick's birthday, so everybody wish him a happy b-day!

Top Ten Concerns About Soar


10.  Will we have a workshop at Georgia Tech during the '96 summer olympics?

9.  100,000 chunks take up too much memory on my workstation

8.  Should get Billy Joel to write an official Soar theme song

7.  Lloyd Bridges

6.  One of the default productions has a name 111 characters long

5.  Those pesky attribute-impasses!

4.  Still no Tetris-Soar

3.  P.I.'s should change their middle names to "Rodham"

2.  Don't have a Soar logo or Soar t-shirts, hats, & coffee mugs

1.  Not enough celebrity cameos in the Soar video

From Bob Doorenbos [] Fri, 18 Apr 1997 12:56:52 -0700

Back to Table of Contents

(G10) Resources for teaching Soar

Soar has been taught as a component of non-programming classes on cogntive architectures at several universities, CMU, Michigan, Sterling in Scotland, Japan at least. At Nottingham it had been two weeks of two hours per week lectures in an advanced undergraduate class.

If you want them to program with Soar, that might be difficult to do to a great depth in two weeks, but as Michigan folks and Ritter and Young have offered hands-on one-day tutorials, so clearly you can cover something in a day. Note that the day is about 6 hours of instruction. This can take at least 6 hours of instruction in a university class to cover, or two to three weeks in a class, more if you give homework. In class you get more out of it because the exercises are done in more detail. The resouces you should look at are the tutorials (psychological, still up at Nottingham,, and the tanksoar / eaters Soar environments are available at the Michigan web site) are not only engaging, but simplify the programming a bit as well through the environment.

Back to Table of Contents


(G12) The History of the Soar Interface

-FER 10/6/00

The first Soar interface was probably the command line from OPS5. One of the first Soar graphical interfaces was written by Amy Unruh and ran on TI lisp machines. Brian Milnes also wrote a graphical interface that ran in Common lisp under X windows. Blake Ward probably wrote the first Emacs mode for Soar. Frank Ritter revised this, and then Mike Hucka revised it, and then Frank revised it, and this went on for a while until it went to Mike and stayed at Michigan. While it was with Frank there was a submode for writing TAQL code (Ritter, 1991b). Various reports were included in the Soar workshop proceedings. There was a manual (Ritter, Hucka, & McGinnis, 1992) . These were fairly widely used systems, maybe 1/2 of the Soar users used them at the time. This mode is still available.

Frank Ritter wrote a graphic user interface for Soar, the Developmental Soar Interface, or DSI, in Common Lisp using Garnet. This was reported in his thesis (Ritter, 1993; Ritter & Larkin, 1994) and at CHI (Ritter, 1991a) . It was used to generate the initial polygons for the Soar video (Lehman, Newell, Newell, Altmann, Ritter, & McGinnis, 1994) . This interface probably had about 10 users at the most, and was abandoned when Soar was implemented in C.

The Tcl/Tk Soar Interface (TSI) is a successor semi-graphical interface started around 1996 taking advantage of including Tcl/Tk with Soar (Ritter, Jones, & Baxter, 1998) . Numerous people have now contributed to it. It is currently being developed at Michigan.

In 1995, a rationalised list of commands aliases was proposed for the command line (Nichols & Ritter, 1995) . These were used in Soar7 and I believe in Soar 8. An unpublished study supported the results that even novices could profit from aliases.

New interfaces to Soar include a revised version of the TSI (version 3, 6/00), which includes viewers for working memory tree, production match, and chunks (contact Karen Coulter ( and/or Mazin Assanie ( A Soar debugger to provide greater control over breakpoints, etc. is also in the works (contact Glenn Taylor, Visual Soar is an environment in Java to help make sure that when writing Soar programs that all attribute names are correct, and to cut and paste and reuse attribute names and sets of names. Laird, Jones, and Bauman at Michigan is working on this effort. A related effort by Tony Hirst is ongoing at the Open University (


Lehman, J. F., Newell, A., Newell, P., Altmann, E., Ritter, F., & McGinnis, T. (1994). The Soar Video. 11 min. video, The Soar Group, Carnegie-Mellon University.

Nichols, S., & Ritter, F. E. (1995). A theoretically motivated tool for automatically generating command aliases. In CHI 95, Human Factors in Computer Systems. 393-400. New York, NY: ACM.

Ritter, F. E. (1991a). How the Soar interface uses Garnet. Video (2 min.) shown at the Garnet user interface development environment special interest subgroup meeting at the 1991 Human Factors in Computing Systems Conference (CHI'91).

Ritter, F. E. (1991b). TAQL-mode Manual. The Soar group.

Ritter, F. E. (1993). TBPA: A methodology and software environment for testing process models' sequential predictions with protocols (Technical Report No. CMU-CS-93-101). School of Computer Science, Carnegie Mellon University, Pittsburgh, PA.

* Ritter, F. E., & Larkin, J. H. (1994). Using process models to summarize sequences of human actions. Human-Computer Interaction, 9(3), 345-383.

Ritter, F. E., Hucka, M., & McGinnis, T. F. (1992). Soar-mode Manual (Tech. No. CMU-CS-92-205). School of Computer Science, Carnegie-Mellon University.

Ritter, F. E., Jones, R. M., & Baxter, G. D. (1998). Reusable models and graphical interfaces: Realising the potential of a unified theory of cognition. In U. Schmid, J. Krems, & F. Wysotzki (Eds.), Mind modeling - A cognitive science approach to reasoning, learning and discovery. 83-109. Lengerich, Germany: Pabst Scientific Publishing.

Back to Table of Contents

(G12) Soar in the news

Read the report on Soar in New Scientist.

Back to Table of Contents

Section 2: Technological Issues

(T1) How can I tie Soar to other pieces of software/simulate an external world?

There are several ways that Soar has been tied to other pieces of software. A now slightly out of date overview is available from:

Ritter, F. E., & Major, N. P. (1995). Useful mechanisms for developing simulations for cognitive models. AISB Quarterly, 91(Spring), 7-18.

A list, in order of complexity, is:

You can tie Soar to itself through multi-agents, that is, having multiple Soar agents and having them talk with each other. See the next question.

Back to Table of Contents

(T2) How can I do multi-agent communication with Soar 7?

[I believe this is originally by Tom Head, around Oct '96.]

Reading and writing text from a file can be used for communication. However, using this mechanism for inter-agent communication would be pretty slow and you'd have to be careful to use semaphores to avoid deadlocks.  With Soar 7, I see a natural progression from Tcl to C in the development of inter-agent communication.

1. Write inter-agent communication in Tcl.  This is possible with  a new RHS function (called "tcl") that can execute a Tcl script. The script can do something as simple as send a message to a simple simulator (which can also be written in Tcl).  The    simulator can then send the message to the desired recipient(s). You could also do things such as add-wme in a RHS but I'd advise against it since its harder to see what's going on and more error prone.

2. Move the simulator into C code. To speed up the simulated world   in which the agents interact, recode the simulator in C.   Affecting the simulator can be accomplished by adding a few new Tcl commands. The agents would be largely unchanged and the system would simply run faster.

3. Move communication to C.  This is done by writing Soar I/O functions  as documented in section 6.2 of the Soar Users Manual. This is the fastest method.

Back to Table of Contents

(T3) Why is "send" in Soar different from "send" in Tk? or, What do I do if my soar process comes up as 'soar2'?

[This stuff will be subject to some change in Soar 7.1, I suspect, -FER] in Soar is and is not different from "send" in Tk. By default, Soar's send is different from Tk. When Soar 7 is compiled with Tk, and -useIPC is specified on the command line at runtime, Soar's send is the same as Tk.

To support multiple agents, Soar 7 takes care of all the overhead of creating and maintaining multiple interpreters (which wasn't supported by Tcl < 7.6). Soar 7 creates a flat space of interpreters -- no single interpreter is the supervisor or owner of another. To allow for communication among agents, Soar uses the "send" command. Tcl itself doesn't have a "send" command, it comes from Tk. But we didn't want to require Tk (i.e., X Windows) in order to run Soar. So Karl wrote an X-server-less version of "send" that could be used to support multiple agents in soar when Tk was not compiled in. This version of send works only for agents/interps within the same process.

Tk's send function registers with the X server to use IPC's (interprocess communications). It tries to register using the name of the application. IF, when Tk/send registers, the X server already has a process by that name, then the name gets a number appended to it so that the name will be unique and then the registration can be done. Then Soar/Tk/send also changes the name of the interpreter to match the process name that was registered by the X server. Through the X server, interpreters can can communicate with other interpreters in other processes.

What was happening to novice and not-so-novice Soar users who wanted to test applications and run multiple copies on the same machine was this: Start the first copy, soar.soar gets sourced to start the application, and "soar" gets registered with X server (invisible to the soar user). Everything (gui etc) comes up fine. Start the 2nd copy: soar interp gets renamed to soar2, no soar2.soar file is found, so no file gets sourced and the application doesn't run as expected. This was happening to nearly all the soar developers at Michigan. This was also happening for an COG SCI class [at Nottingham] trying to all run the same application (subtraction world) to explore theories of learning. It was VERY confusing. But, we had this nice little workaround since Karl had written the "send" command for Tcl-only Soar that avoided registering with the X server.

Since it was anticipated that most Soar users would not be starting out wanting IPCs ("what's that?"), we made the default method for running Soar use the IPC-less version of send. For those users savvy enough to run multiple processes and want to communicate among those processes, we added the commandline flag -useIPC. The doc could be more explicit about how "send" works in Soar, but the -useIPC flag is in the help pages. And I still believe this was the right way to go. Otherwise we would have had to tell users to have as many soar[n].soar files as they ever thought they would need to support running multiple copies of an application if Tk was compiled in their version of Soar. OR we tell the users who need IPCs (far fewer in number), oh yes, you need to specify -useIPC when you start up soar.

Now that Tcl 7.6 supports multiple interpreters, Soar no longer has to manage the overhead, we no longer have to create our own methods for communicating among agents, and we won't be shadowing Tcl or Tk commands. It also looks like Soar won't be autoloading any 'interpname'.soar files, so this whole problem goes away (only to be replaced by something else, no doubt). And Soar programmers who want to communicate with other agents and processes will have to read the Tcl doc to figure out how to do it =8-O ;)

Taken from: "Karen J. Coulter" []

Subject: Re: [Soar-Bugs #85] Why is "send" in Soar different from "send" in Tk?

Date: Fri, 11 Apr 1997 17:42:16 -0400 (EDT)

Back to Table of Contents

(T4) How does Soar7 differ from Soar6?

Question from Monica Weiland []

Basically, the Soar kernel architecture in Soar 7 is the same as what is in Soar 6, with additional bug fixes, and changes to the timers to be more accurate and informative when the 'stats' cmd is issued. However, the timers don't work on the Mac just yet. There were also changes to using multiple agents and the NNPSCM is the only PSCM model supported (in 6, both NNPSCM (no explicit problem space slot) and the PSCM (explicit problem space slot) were supported). The advantages of Soar7 include all the user extensions that can be done by using Tcl for the user interface.

In the Soar distribution there is a tool for converting from Soar 6 format productions to Soar 7. It was written by Doug Pearson and it's called convert (written in C). I don't know if it is included in the Mac distribution, but I would assume it is. It does a good job of converting productions; most applications run after being processed by this routine. If Monica has the SimTime productions, she should be able to convert to Soar 7. If she has trouble with the conversions, she can contact me and I'll help her figure them out.

Answer from: "Karen J. Coulter" [] Date: Mon, 9 Jun 1997

There are also some notes available noting some explicet changes in the command set that were presented as part of a talk at the Soar 15th workshop. These notes are out of date, but not so out of date to be useless. The directory where to find and

Answer from: "Clare Bates Congdon" [], now physically at Bryn Mawr College. Date: Mon, 14 Jul 1997

Back to Table of Contents

(T5) How can I use sockets more easily?

Using sockets with Soar is not well-documented, but it has been done. Socket communication is included in the Eaters and TankSoar applications (which come with a tutorial document) and sockets have also been implemented with C code using a library written at Michigan called SocketIO. Eaters and TankSoar and the Soar 8 Tutorial are available on the Soar "Getting Started" web page, and SocketIO can be found near the bottom of the "Projects/Tools" web page.

http://ai.eecs.umich.e du/soar/getting-started.html /projects.html

Scott Wallace ( added socket communication to Eaters (and TankSoar uses the same code) and Kurt Steinkraus ( wrote SocketIO. Kurt is no longer at Umich, but his email gets forwarded.

Answer from: "Karen J. Coulter" [] Date: Fri, 4 Jun 1999

Back to Table of Contents

(T6) What was TAQL?

TAQL (Task AcQuisition Language) was a higher level programming language written for to work with Soar 5. The best citation for it that I know of is Yost, G. R., & Newell, A. (1989). A problem space approach to expert system specification. In Eleventh International Joint Conference on Artificial Intelligence. 621-627. I believe that there was also a journal article on it.

Copies of the source code and manuals are probably available at the software archive at CMU

The TAQL compiler was written in LISP. You would load TAQL into a running lisp. You put in a file templates that were designed to do common PS operations, such as create and implement an operator or a problem space. When these templates were loaded (or compiled) they would produce Soar 5 productions. These template produced productions could be augmented with additional hand-written productions.

There was also a mode in GNU Emacs to help write TAQL code, it would balance braces of various sorts and insert templates for you to fill out. It's written up in Ritter's PhD thesis. It showed that TAQL had a more complex syntax (by its grammar) than the C programming language had.

My belief about why TAQL is no longer with us is this: It was an initial pass at a necessary level in Soar. A successor is badly needed because it was a good idea -- it was a higher level language so that users did not have to write Soar productions to generate behaviour on the problem space level. It had several flaws, however. It had a manual and a short tutorial. Gregg Yost using TAQL was probably the fastest that Soar code has ever been written.

The syntax was large. This could be because there is not a simple syntax that will do the job, or it could be because it was a first draft. This complex syntax made it slightly hard to use.

TAQL ran with learning off. Learning could be turned on, but things broke. I don't have access and I don't think a full analyse of how things broke were ever done.

TAQL was written in Lisp. When Soar moved to C and Tcl/Tk, TAQL had to be translated. Greg Yost graduated around this time, and it was not carried forward. It was a large project and was most naturally written in Lisp. It would be harder, but not at all impossible to write in Tcl.

Back to Table of Contents

(T7) What does using a ^ flag buys you apart from providing a conventional label within which to enable operator proposition?

From Randy Jones:

My opinion is that the ^problem-space flag is an anachronism that should be discarded, especially for non-trivial Soar programs.  The flag originally arose from Newell and Simon's problem-space hypothesis, and the notion that people tend to employ specific sets of methods and goals for specific types of problems.  What this "flag-based" representation neglects, however, is the potential for sharing methods and goals across types of problems that we might normally view as being in distinct problem spaces.  In TacAir-Soar, for example, we have *many* operators that can apply in a variety of different states, independent of the problem-space flag on that state.  In general (and again in my opinion), operators should be sensitive to patterns of data represented on the "current state", rather than being a slave to a single, discrete, problem-space flag.  This allows the use of operators to transfer across problem spaces in useful, and sometimes surprising, ways.  Under this view, problem spaces "emerge" from patterns of data, rather than being defined by a single flag.

From Richard Lewis:

While I agree with much of what Randy says, I wouldn't be too quick to discard the use of a problem-space flag.  The problem-space flag permits the agent to decide (based on some knowledge) to solve its problem in some particular way, then to change its decision later and attempt a different way, etc. It is an additional layer of deliberate control that allows the agent to 'hold in place' the outcome of some decision and use that decision to guide problem solving behavior over a period of time that extends beyond a single decision cycle.  Thus, the agent is not just slave to whatever immediate associations come to mind. What I'm really advocating is a view that keeps a mix of the data-driven, opportunistic style that Randy describes, along with the ability to exert more control over some extended periods of time.  Such a mix may hinge in part on using the problem space flag in ways that we haven't usually done in the past: as search control rather than generator.  There's a sense in which this kind of mix can't be discarded as long as it is architecturally possible, the system is learning, and we can't see any clear reasons why the agent in principle can't arrive, via learning, at a point where it behaves in such a way.

From John Laird:

I agree with just about everything Randy said. On the ^ issue - in earlier versions of Soar, the problem space was selected just like the operator, and thus was open to preferences. However, for the reasons Randy mentioned (problem spaces may be more emergent from many properties of the state than just a specific symbol) we abandoned the selection of the problem space.  For many tasks, having a problem space symbol might be a good way to discriminate during operator selection.  The convention that I've adopted is to copy the name of a super-operator to be the name of the state created below it. This doesn't cover tie impasses or state no-change, but works very well for operator no-changes.

Back to Table of Contents

(T8) Soar and design models

From Gourab Nath:

Implemented SOAR-based prototype systems for engineering design exist in the following domains:

(1) Elevator configuration design (2) Civil Engineering design : floor systems design (3) Chemical Engineering process design (4) Computer configuration design: R1-SOAR (5) Algorithm design

Back to Table of Contents

Section 3: Advanced Programming Tips

(APT1) How can I get log to run faster?

I'm using the log command record a trace for a very long simulation (15k+ decisions) I'm running. is there a "quiet" mode so that the trace doesn't redundantly print the screen? the printing really slows things down. is there a clever/obvious way to presently do this? maybe it's a feature to consider in the future??? thanks.

There isn't a quiet mode on the log command, but in general for any xterm, ^O toggles the output to the screen. If you only want the output of the trace, you can redirect it to a file using output-strings-destination. I believe then the text would be sent only to the file and not to the screen.

Answer from: Karen J. Coulter [] Date: Mon, 16 Dec 1996 13:01:50 -0500 (EST)

Back to Table of Contents

(APT2) Are there any reserved words in Soar?

This is a slightly odd question, for Soar is a production system language, not a procedural language like Pascal. But we know what you mean. What symbols have special meaning, and how can I use them and how do I have to use them?

The most important symbol is 'state'. To start their match, productions have to start with a clause that starts with the state, e.g.,

(state ^attribute value)
On the top state, there are a few attributes that the system uses. These are ^IO, which holds IO information; ^superstate, which holds a pointer to the superstate or nil if it's the top state; ^type, which indicates if the object is a state, operator, or user defined; ^operator, which holds the current operator. In lower states caused by impasses, there are additional attributes: ^attribute, which is the type of object causing the impasse, such as state or operator; ^choices, which holds the tied choices in a tie impasse, or none in a no-change impasse; ^impasse, which indicates the type of impasse, such as no-change; ^quiescence, which indicates if the impasses happened with rules left to fire (nil), or if the impasse happened with all the rules fired (t). If quiescence is checked in an impasse, a chunk is not built. This is a way of avoiding learning based on a lack of knowledge. These attributes can all be matched by user productions, but either cannot or should not be changed by the user.

Many modelers use ^problem-space to be treated like a reserved word. It used to be modifiable only by an explicit decision by the architecture. Now it can be done by models directly. Most objects have an ^name. It is nearly a necessity to name your operators, and if states are named, their names will appear in the trace.

The default rules use their own conventions for using attributes. These conventions amount to reserved words that your models can use and sometimes, for example, the selection knowledge, encourages domain knowledge to assist in evaluating objects. If you are not sure about what attributes are there, just print out the objects, for this information is enough to get you started.

Back to Table of Contents

(APT3) How can I create a new ID and use it in the production?


Jonathan Gratch [] wrote:

I've noticed the following:

the rule

sp {....

( ^foo (make-constant-symbol |foo|) + &amp;)}

expands to

sp {....

( ^foo (make-constant-symbol |foo|) +

^foo (make-constant-symbol |foo| &amp;)}

The workaround solution, if I remember correctly, involved a two step process of generating your symbol and then separately putting it to whatever use you had in mind. Not being an expert at writing Soar productions, I may be way off base on this one, but I did not want to leave you without any initial response to your bug report. I do not believe any kernel solution to this irritating behavior would be easy to
implement, but that is just a guess at this point.If you do not come up with a workaround, let me know and I will look into this
further. Heck, let me know either way, the information would make a good addition to the soar-bugs archives or perhaps the FAQ.

From: Aladin Akyurek []

Date: Thu, 13 Mar 1997 21:08:32 +0200

A workaround is to split the production that creates a value by make-constant-symbol for an attribute that is intended to be a

sp {gratch-1

(state ^superstate nil)

( ^foo (make-constant-symbol |foo|))}

sp {gratch-2

(state ^superstate nil ^foo <v>)

( ^foo <v> &amp; )}

Back to Table of Contents

(APT4) How can I access Tcl and Unix variables?

soar_library and default_wme_depth, for example, are defined as a global variable, and all Soar files can be obtained through relative path names from it. On the Mac this is a bit trickier, but doable as well. Check out the TSI source code for examples.

Unix environmental variables are also available through the "env" matrix of variables (e.g., $env(MANPATH). Advanced users can also set variables in their shells by hand or with init files.

You should keep in mind that the Tcl scoping of variables is non-intuitive (to us, at least, at times) and it is a common problem in setting up paths and installation flags.

This sort of problem is becoming a trend as its easy to overlook. All Soar global tcl variables, such as $default, need to be defined with a tcl "global" command when used in a script. When procedures call procedures that call scripts which call scripts ..., your variable scope will change!

If variables are not visible as you expect them to be, often the problem is that they are global but not declared in your function or file. Insert a 'global var_name' and often the variable will appear again.

Expanded from email between Tom Head [], Karen J. Coulter [], and on soar-bugs, Tue, 25 Mar 1997 12:33:26 -0500, and later email as well.

Back to Table of Contents

(APT5) How can I access Soar objects?

Question from Harko Verhagen [], How do I get access to WMEs?

Answer from Bruce Israel [], Fri Dec 20 1996

If you're working in soartk, in the TCL shell you can use the function "wmem" to retrieve WMEs. "wmem" prints its output, but you can use "output-strings-destination -push -append-to-result" to get it into a form you can use programmatically.

Here's some TCL routines I built for accessing WMEs. You can use the routines wm_elts, allobs, and wm_value for different types of retrievals within TCL code.


utility routines for WM retrievals

Written by Bruce Israel [], Fri Dec 20 1996

Copyright ExpLore Reasoning Systems, Inc. 1996.  All rights reserved.

member- is ITM an element of the list LST?

Usage: member ITM LST

proc member {itm lst} {

    if {-1 == [lsearch -exact $lst $itm]} { return 0} else { return 1}}

addset - add an item to a set

proc addset {itm lst} {

    if {! [member $itm $lst]} {

        lappend lst $itm


    return $lst


wm_elts - Return triples of all WM elements matching pattern

proc wm_elts {ob attr val} {

    output-strings-destination -push -append-to-result

    set wmemstr [wmem "($ob ^$attr $val)"]

    output-strings-destination -pop

    set def ""

    while {[scan $wmemstr "%\[^\n\]%\[ \t\n\]" wm_elt ws] > 0} {

        set ct [scan $wm_elt "(%d: %s %s %\[^)\])" time nob nattr nval]

        if {$ct > 0} {

            lappend def "$nob $nattr $nval"

            set len [string length $wm_elt]

            set len [expr $len + [string length $ws]]

            set wmemstr [string range $wmemstr $len end]

        } else {

            set wmemstr ""



    return $def


# Return all WM objects matching the specified ATTR / VAL

# e.g.

#    all objects - allobs * *

#    all states - allobs superstate *

#    top state - allobs superstate nil

proc allobs {attr val} {

    set obs ""

    foreach wm [wm_elts * $attr $val] {

        set obs [addset [lindex $wm 0] $obs]


    return $obs


# Return the value(s) of an attribute of a particular id.

# Multiple values are separated by newlines.

proc wm_value {id attr} {

    set wmitems [wm_elts $id $attr *]

    set res ""

    foreach item $wmitems {

        set val [string trim [lrange $item 2 end] "| \t\n"]

        set res "${res}\n${val}"


    return $res


Back to Table of Contents

(APT6) How can I trace state changes?

The -trace switch to the print command is intended to be used in conjunction with a Tcl command in a RHS to provide a runtime diagnostic tool.

Andrew's [Howes's suggested] "trace" RHS function was intended to provide a way to print out objects during production firing. I thought it better to add a "-trace" option to the print command and have that command be used via the "tcl" RHS function:

syntax: print -trace [stack-trace-format-string]

Sample RHS usage: (tcl |print -trace | | | <x> ) uses a nice default format string and
prints <x> out with indenting appropriate for (goal) state

Expanded from email between Tom Head [], Kenneth J.
Hughes [], Karen J. Coulter [], and Clare Congdon. Thu,
16 Jan 1997 18:46:54 -0500, and other emails.

Back to Table of Contents

(APT7) How can/do I add new Tcl/Tk libraries?

Question from Rich Angros: I want to add some other TCL widget extensions into tksoar. Does the tcl/tk code have any special modifications that are specific to Soar? What restrictions are there on the version of tcl/tk used?

The versions of Soar that are currently available on the web pages all require Tcl 7.4 and Tk 4.0. In order to allow for multiple agents in Soar, we had to extend Tcl within Soar and so we modify some of the Tcl files and keep a private copy. Then when Soar is built, the linker uses the "private' copies of these routines instead of the ones Tcl comes with. So you can pull Tcl 7.4 and Tk 4.0 off the Tcl web sites and use them when building Soar, but Soar will link in a few extended routines of its own. You should be able to add other Tcl extensions in a straightforward manner, without any concern for Soar's modifications of Tcl. In fact, Soar used to be distributed with Blt, but it was cumbersome to support building it on multiple platforms, and we weren't sure how much it was used, so we took it out. You would add Tcl extensions in the soarAppInit.c file, just as you would add it to tkAppInit.c

Soar 7.1 (to be released soon) uses Tcl 7.6 and is completely decoupled from the Tcl routines, since Tcl 7.6 provides support for multiple interpreters. So from Soar 7.1 on, you should be able to upgrade Soar or Tcl packages independent of each other.

From "Karen J. Coulter" [] Date: Mon, 9 Jun 1997

Back to Table of Contents

(APT8) How can and should I use add-wme and remove-wme?

This is a relatively long exchange noting how to use add-wme and remove-wme, while acknowledging that it violates the PSCM (or even the NNPSCM).

From: Harko Verhagen 

Sender: European SOAR research communications 


Subject:      soar io cleaning

Date:         Wed, 20 Aug 1997 13:31:02 +0200

I'm still working on my multiagent simulation soar code. a problem I encounter is that it seems hard to remove information that was added with add-wme. Each agent has some tcl code to take care of communication with the environment (including other agents). files are used to store information that needs to be transfered. the info gets read in tcl and is tranferred to working memory with add-wme. This information may of course trigger some productions in Soar. However, the information should not persist after some processing. In Soar 5 a elaborate state production did the trick by removing the message in a rhs action.  In Soar 7, the production fires but its effect does not show in the wmphase. using a tcl call to remove-wme makes Soar crash.  Any way around this?

excerpt of trace:
message contains y x command A find to

=>WM: (167: I7 ^from-whom x)

=>WM: (168: I7 ^to-whom y)

=>WM: (169: I7 ^mode command)

=>WM: (170: I7 ^item |A|)

=>WM: (171: I7 ^subtask find)

=>WM: (172: I7 ^misc to)

--- Preference Phase ---

Firing warehouse*propose*operator*reception-mode


(O17 ^desired D1 + [O] )

(O17 ^name reception-mode + [O] )

(S4 ^operator O17 +)

Firing warehouse*elaborate*operator*wait





Firing reception-mode*elaborate*state*remove-receive-message


(I6 ^message I7 - [O] )

Firing reception-mode*terminate*operator*receive-message


(S5 ^operator O19 @)

Firing reception-mode*reject*operator*dont-receive-message-again


(S5 ^operator O19 -)

Firing reception-mode*propose*operator*evaluate-move-find-yes


(O21 ^misc yes + [O] )

(O21 ^item |A| + [O] )

(O21 ^subtask find + [O] )

(O21 ^mode command + [O] )

(O21 ^to-whom x + [O] )

(O21 ^from-whom y + [O] )

(O21 ^name send-message + [O] )

(S5 ^operator O21 +)

--- Working Memory Phase ---

=>WM: (227: S5 ^operator O21 +)

=>WM: (226: O21 ^misc yes)

=>WM: (225: O21 ^item |A|)

=>WM: (224: O21 ^subtask find)

=>WM: (223: O21 ^mode command)

=>WM: (222: O21 ^to-whom x)

=>WM: (221: O21 ^from-whom y)

=>WM: (220: O21 ^name send-message)

Bob notes that it is indeed possible to shoot yourself in the foot with add-wme (just as modifying the calling stack would be a bad idea in any programming language).

From: Robert Wray 




Subject: [Soar-Bugs #225] Re: soar io cleaning

Date: Thu, 21 Aug 1997 17:30:52 -0400 (EDT)

(I'm cc'ing this to soar-bugs for two reasons, even though it might

not be a bug per se.  First, the error message that Harko reported to

me and that I replicated below is somewhat misleading.  As far as I

can tell, the new instantiation has been added to the instanitation

list and so should be available in p_node_left_removal (rete.c) for

adding to the retraction list -- which is where the program aborts

because it can;t find a relevant instantiation.  Second, because folks

seem to want to add and delete WMEs from the RHS with tcl, my guess is

that this problem may become frequently reported and thus worth

documenting now.)


Let's work on the second problem first:

I was able to replicate the problem you are having when my productions

attempted to remove a WME that was also tested in the LHS.  For

instance, consider this simple example:


sp {elaborate*state*problem-space*top

(state ^superstate nil)


( ^problem-space



^name top)}

sp {elaborate*state*create-some-WMEs

(state ^ top)


;# This WME gets timetag 7

( ^deep-structure <ds>)

;# This WME gets timetag 8

(<ds> ^simple-structure *yes*)

;# This WME gets timetag 6

(tcl |add-wme | | ^added-via-add-wme *yes*|) }

sp {elaborate*remove-structure


(state ^deep-structure <ds>

;# ^added-via-add-wme


(<ds> ^simple-structure *yes*)


( ^new-augmentation *yes*)

(tcl | remove-wme 6|)}

If I try to remove any of the WMEs I test in the LHS of this

production (eg, timetags 6, 7 or 8), I get the problem you reported in

your message, namely:


Internal error: can't find existing instantiation to retract

Soar cannot recover from this error.  Aborting...


Soar (or at least the implementation in C but I think it's pretty easy

to say the PSCM of Soar as well) assumes that WMEs do not disappear

during the preference phase. In this case, because you are removing a

WME directly from a tcl call in the RHS, this assumption is violated.

Soar is attempting to retract an instantiation (or, more specifically,

add an instantiation to the retraction list) while in the process of

firing the instantiation.  In a normal situation, this simultaneous

fire and retract is impossible because the architecture doesn't allow

WME changes during the preference phase, just preference changes.

Your production violates that architectural constraint, with the

resulting error.


Again, there are workarounds (and I'll describe one in a separate

message).  But, you really shouldn;t be doing this.  You should only

be creating and deleting input WMEs when the input function is called

in the INPUT PHASE, as I described yesterday.  And you should

use the preference mechanism to remove any regular Soar WMEs.



 In his second message, Bob Wray notes that using add-wme is difficult, but offers
some ways of using add-wme, and notes that it violates good taste.From: Robert Wray 

Sender: European SOAR research communications 


Subject:      Re: soar io cleaning

Date:         Wed, 20 Aug 1997 11:05:10 -0400


I have a suggestion for a workaround to your problem and what I think

might be a better, long-term solution.  I'll discuss the long-term

solution first, because I think it's the best route to follow.

The reason remove-wme did not work for you is that the

command requires the integer time tag value to identify the WME to be

removed.  It is not easy to access the timetag through productions; it

would require a few tcl calls and some text parsing to do accomplish

this. (I haven't actually tried to do removal this way -- it may be

impossible but my guess is that it's not impossible, just very

difficult.)  The difficulty is not an oversight in the design of Soar

-- it is purposeful.  All WMEs except input WMEs should go through the

decision process (evaluation of preferences).  Input WMEs are added

only through the I/O link.  Thus, Add-wme and remove-wme were not

really meant to be used in the RHS.  Prior to Soar 7, it was very

difficult to use add-wme and remove-wme in productions; tcl has made

it much easier to disregard these assumptions. (Seth Rogers covered

many of the ways Tcl can violate Soar assumptions in a talk entitled

"Tcl Magic: How to do things you're not supposed to do in Soar" at

Soar Workshop 15.)

A long-term solution to your problem would be to re-implement your

system using Soar's supported I/O mechanism, the ^io link.  In this

case, messages would appear on the input-link of an agent.  Add-wme

would still be called, but it would be called by a tcl input function,

rather than a RHS call.  To remove the message, an operator could

place a command on the output--link to remove the indicated message.

Then, via tcl code in the output function (which has access to the

timetag), the message could be removed from future input with

remove-wme.  There is a simple example in the soar distribution

(soar-io-using-tcl.tcl in the demos directory) that illustrates how to

set up a tcl I/O system.  Chapter 17 of the Soar Coloring Book

( also covers I/O (but at a

very high level).

However, maybe you need a working prototype right away?  Although I

strongly encourage the above solution, here's a workaround for your

current problem:

You can't use remove-wme for the reasons I described above.  You can't

use production preferences because a WME created with the add-wme

command has no preferences; it is just added to WM without going

through the decision process.  (I'm not familiar with Soar 5 so I

don't know enough about it to know why the production/preference

removal worked there; my understanding of Soar 7 is that WMEs created

with add-wme should only be removable by remove-wme, to discourage

non-PSCM WME additions and removals) However, like all Soar WMEs,

everything must be connected to the top state (directly or

indirectly).  So the workaround I'm proposing is to remove WMEs

created with add-wme by removing via preferences the WME that the

added WME was attached to.

For example, instead of attaching WMEs to the state directly, imagine

that there is a place holder for messages called "message-link:"


sp {elaborate*state*message-link*bootstrap

(state ^ top)


( ^message-link <ml>)

(<ml> ^message <nil-for-now>)}


Now, when you want to add messages, you always add messages to the



sp {add-message-with-tcl

(state ^ top

^message-link.message <message> )


(tcl |add-wme | <message> | this-is-a-message *yes* |) }


Then, when you want to remove a message, you just remove the message-link

(and you'll also want to add a new message-link for a future message):


sp {some-operator*apply*remove-message-link*and*create-new-message-link

(state ^operator <o> ^message-link <ml>)

(<ml> ^message <message>)

;# (whatever tests you want to make to determine if the message should be


(<o> ^name remove-message)


( ^message-link <ml> - <ml2> +)

(<ml2> ^message <nil-for-now>)}


When this production fires, it will remove the existing message-link, which

includes, as substructure, the WME you created with add-wme.


Although this convention will work, it is a hack and does not

represent the best way to solve the problem.  But it will allow you to

get your system running in a few minutes.  In the long run, as I

suggested before, I'd use Soar's I/O link for input and output.


Hope these ideas have been useful.  I'm sure others will have other

ideas and additional suggestions about the ones I've described here.



Another user comments that this approach can be fragile, but that if done in as theoretically a way as possible it is workable. From: Hongbin Wang  Sender: European SOAR research communications  To: Subject:      Re: soar io cleaning Date:         Wed, 20 Aug 1997 13:17:39 -0400
  Harko Verhagen wrote: From: Harko Verhagen  Sender: European SOAR research communications  To: Subject:      Re: soar io cleaning Date:         Wed, 20 Aug 1997 17:11:11 +0200
  i *DO* use the io-link, add-wme is used in tcl procedures hooked to the io-cycles of soar as described in the soar-io demo. the remove-wme is also in a tcl procedure which is called from RHS and the timetags are global vars in tcl. i now also have a workaround but it looks like a hack to me. i just dont test for the presence of the message that has to be removed but for a flag i have on the operator. for some reason removing the messsage with a structure like: ^item1 - is not enough, the tcl removal procedure is also necessarry to avoid looping (it makes retracting impossible).
  I encountered the same problem some time ago. The way I adopted is, 1) using productions to copy messages from io-link to some other place (say, internal situational model) in WM; 2) All decision makings are always based on the internal situational model instead of the io-link (since it is volatile); 3) add-wme and remove-wme are safe in io producures; 4) as soon as messages is removed from io-link, they will disappears from the situational model too.
  I found Bob's answer is very informative, although I didn't quite get the reason why remove-wme doesn't work. It seems to me that remove-wme is quite fragile and in some cases it simply makes the system crash, even it is called in a tcl procudure and is given the integer timetag. We have actually been warned about this from the on-line help. However, I did find it is safe when I clearly distinguished problem-solving from io.
  Back to Table of Contents

(APT9) Frequently found user model bugs, or How can I stick beans up my nose metaphorically in Soar?

There is intended to turn into a rogue's gallery of frequently found bugs that are hard to diagnose on your own, but are not bugs in the architecture per se.
  • If something fishy happens where items drop out of memory and come back in again in a cycle, check I and O-support. If you have a production cycling (firing repeatedly on the same symbols, the rule does not have o-support like you think it does, and it is removing one of the values that matches its conditions, which forces it to retract and its results to retract. The rule now matches again and the loop continues. You need to rewrite the rule to give it o-support, either by fixing its clauses so that they get o-support, giving it o-support explicitly, or by breaking its results up into o-supported clauses and non-o-supported clauses.



  • If something fishy happens where items drop out of memory and don't come back in, check for attribute value ties. If two values are both acceptable, but not indifferent and not parallel, they will clobber each other and neither will appear.



  • If an operator is proposed but not selected, and there are preferences for making it best, you may wish to check to see if the operator has an acceptable preference. In order to be selected, operators must be acceptable. Best is not good enough on its own.



  • Creating a link in a subgoal to a supergoal. This is an error because it can make the supergoal a result of the subgoal and then all hell breaks loose. [ed. I think, essentially returning a result to a subgoal that's not there any more.]

  • Answer from John Laird, Thu, 30 May 1996 09:53:07 PDT

  • If you change the state of Soar with tcl calls, you can get back to the shell fairly quickly. For example, a production that deletes itself.

  •      sp {delete-me

            (state  ^superstate nil)


           (tcl |excise delete-me|)}

    Tom Head (16/1/97) noted that he didn't believe that the ramifications of all the possible tcl RHS actions are guarded against, such as (tcl |init-soar|), (tcl |source monkey-time.soar|), or (tcl |soar|). If you are looking for a way to shoot yourself in the foot, using a tcl RHS action is easier than most.

  • If your code is missing a close bracket, Soar will hang, as this exchange of emails explains.
  • Date: Tue, 15 Apr 1997 13:54:20 -0400
           From: Tom Head <>
           To: Aladin Akyurek <>
           Subject: Re: [Soar-Bugs #197] missing closing brace makes    Soar hang
           Aladin Akyurek [] wrote
           In case this is not reported, the production
           sp {x
           (state ^{ &lt;&lt; car bicycle &gt;&gt;)
           ( ^private-vehicle t)}
           with a closing brace missing makes Soar hang.
           On the other hand, if an opening brace is missing, we get:
           soar&gt; sp {y
           (state ^&lt;&lt; car bicycle &gt;&gt; })
           extra characters after close-brace
           soar&gt; --&gt;
           ( ^private-vehicle t)}
           invalid command name &quot;--&gt;&quot;
           invalid command name &quot;(&quot;

       Thanx, Aladin, this is probably another candidate for the FAQ. Conjunctions that are
        not properly enclosed with both "{" and "}" braces confuse Tcl command
        completion when your sp command also uses braces to enclose your production. If you
        replace the outer sp braces from your examples with double quotes instead, you will get a
        more reasonable response. A proper error can not be generated because Tcl either does not
        believe that a production has been completed or completes it prematurely, depending on
        which brace is missing.   
  • Clauses in Soar productions match to whole WMEs. NEW [based on emails with David Carboni and Ken Hughes, May 1998]

  • The user who wrote the production below thought that the rule would match once per state. This is not true, for each clause is matched to WMEs, and if there are no conditions, it will match to all that meet the very basic condition of starting with state. This rule will match to all the WMEs that start with state. It is an interesting exercise to print it out.
           sp {Init*Setup*Proposal
           (state )
           ( ^operator <o> &lt;)
           (<o> ^name initstate)
           From Gourab Nath:
           SOAR hung up while parsing(loading) the productions    under the following situation: I
           had a '}' character within a comment ie. something like this:    #(&lt;o&gt; ^name op1 -^cell
           a)} I cleared } and it was OK

      Back to Table of Contents

    (APT10) Why there seeem to be no preferences in preference memory for (id ^attribute value) triples acquired through C input functions ?

    From Randy Jones

    Working memory elements from I/O are added directly to working memory without going through Soar's preference mechanism. That's why they don't have any preferences. That's also why production rules can't make them disappear (say, with a reject preference), because those WME's just totally bypass the preference process. This is intentional. The idea is that the input link represents &quot;current perception&quot;, and you can't use purely cognitive processes to &quot;shut off&quot; your current perceptions. If you want to remove things from the input link, you have to make the I/O code remove them. If you want the input link to be under the control of cognition, then your rules have tel tell the I/O system (via the output link) to change the values on the input link. The rules cannot do it directly.

    From Karen Coulter:

    C Input functions add wmes using the kernel routine add_input_wme, which surgically alters working memory directly. The preference mechanism is not part of this process. The only way to remove these input wmes is by calling the routine remove_input_wme from your input function. add_input_wme returns the pointer to the wme you added, which you must store statically somehow (on a linked list or something) to later remove the wme with remove_input_wme.I should add the caveat that I didn't actually go back and look at Soar 6, and gave you the answer for Soar version 7 and later, but I'm fairly certain that add_input_wme and remove_input_wme also were in Soar 6. (look in io.


    [End of The Soar less than Frequently Asked Questions List: Appendum to Soar FAQ]

    Programming Questions

    How do I change the value of an attribute? What are the cognitive capabilities of Soar? (Todd Johnson is dealing with this) Interfacing Soar to other systems EPIC to Soar sockets to Soar AppleEvents to Soar -- Tools and Utilities -- ------- One technique for data chunking: Suppose you see a set of keys, and you want to infer "lock" whenever you next see keys.  When you subgoal, to build your chunk, you cannot consider lock in the top state since that would go into the chunk.  So you need to think about other things in the environment that can create a "best" preference for lock, so that that production's conditions do not go into the chunk, but the fact that the subgoal returned lock does. -------Doug's Questions and Answers  10) Interfacing Soar to other systems         How do I write a simple tcl world and interface soar to it This changes too fast to make it worth writing now.  17) Tools and utilities for Soar         How can I find out why that condition is in my chunk                 Use the "explain" command.  Details above.