Soar 7.1 Release Notes (Proposed) Christopher R. Waterson waterson@eecs.umich.edu 5/25/97 1. Overview =========== Soar is no longer a stand alone process. Instead, it is implemented as a dynamically loadable Tcl extension, and is loaded into a Tcl interpreter at run time. More specifically, Soar is a Tcl package that can be made available in an interpreter using the "package require" command. When Soar is loaded into an interpreter, a single Soar Agent is created and assigned to the interpreter. In addition, the standard Soar commands (such as add-wme, sp, and watch) are added to the set of commands that the interpreter can process. As would be expected, these commands manipulate the newly created Soar agent appropriately. 1.1 Benefits ("Nuggets") ------------------------ There are several benefits to building Soar as a dynamically loaded Tcl extension. . Soar can be distributed across Macintosh and Windows platforms, as well as the traditional UNIX workstations. By following a simple set of guidelines, a Soar developer can ensure that a program written on one platform will work on any other platform without modification. . A single code base is sufficient to support all of the distributions of Soar, alleviating the need for platform-specific releases. This means that upgrades to the Soar kernel will be available across all releases of Soar, unilaterally. . The Soar source code is independent of the Tcl and Tk implementations. This means that changes to the Tcl and Tk implementation will have minimal impact on Soar. More specifically, upgrades can be made to Tcl and Tk independently of Soar, and vice versa. For example, as of this writing, it is possible to incorporate the Soar extension in to the Alpha release of Tcl/Tk 8.0 with (at most) a relink. Some platforms are even binary compatible. . Soar becomes "just another Tcl package", and can work in concert with other Tcl and Tk packages. For example, Tcl packages exist for supporting the HTTP protocol, running PERL scripts, and interacting with Windows OLE objects. Soar can now act as a "peer service" that can utilize these packages. 1.2 Drawbacks ("Lumps") ----------------------- Nevertheless, some drawbacks do exist in this release. Primary among these is the change to the "user interface". The largest change in this release is the implementation and interface for the multi-agent functions. Our belief is that these functions are currently only in limited use by the Soar community, and so changing them now will have minimal impact on most Soar users. Furthermore, configuration of a Soar installation is somewhat more elaborate. In this release, Soar is a shared library rather than a monolithic application, so careful installation procedures must be followed to ensure that a variety of files are correctly located on the target system. Fortunately, much of this complexity can be mitigated by use of installer programs, particularly on the Macintosh and Windows platforms. 1.3 Philosophy -------------- As noted above, we believe that the majority of current Soar users do not make use of the multi-agent functionality within Soar. Our goal, then, was to minimize the impact of our changes to this majority population of users. In re-designing the multi-agent interface, We attempted to make use of Tcl primitives wherever possible, removing any duplicate functionality within the Soar code base. Furthermore, we chose to make the multi-agent primitives as simple as possible, and to make no assumptions about the way in which the primitives might be used. Our belief is that the builder of a multi-agent system will likely be a sophisticated Tcl programmer, and will prefer to have the full power of the Tcl & Tk architecture exposed to them. 2. Changes to Soar ================== This section describes in detail the changes made to Soar 7.0.4 to create Soar as a dynamically loaded Tcl extension. Specifically, it discusses the impact of these changes on user-level commands. Briefly, the area of greatest change is in the multi-agent facilities. This release of Soar makes use of built-in Tcl facilities to manage multiple agents. Developers who do not make use of these functions will be minimally impacted. 2.1 Starting Soar ----------------- Soar is no longer compiled and linked as a standalone executable. Soar is now a dynamically loaded Tcl extension, which is loaded using the operating system's dynamic linking facilities (e.g., shared objects on UNIX systems, DLLs on Windows). 2.1.1 What to Type ------------------ To start Soar, first start either "tclsh" or "wish" (use wish if you plan to use Tk graphics). Type "package require Soar" (case is signficant!) to let Tcl know you'll be making use of the Soar commands. Now you can use the Soar7 commands to your hearts content! Of course, the "package require Soar" statement can be added to the start of any Tcl script so you don't have to type it every time. Issuing the "package require" statement multiple times in an interpreter has no malicious effects, so re-sourcing a file will not cause problems. 2.1.2 Demand Loading & Soar-specific Variables ---------------------------------------------- The Soar extension is demand-loaded into an interpreter at exactly the time that the first Soar-specific command is invoked, but not before. This means that Soar-specific variables (like "soar_library" and "default") will not be available until the first command is executed. An easy way to ensure that the variables are accessable is to force Soar to load immediately; e.g., by placing the "init-soar" command immediately after the "package require" statement. 2.1.3 No Automatic Sourcing --------------------------- Soar will no longer automatically source a default file when creating new a agent. For example, in Soar7 the "soar"; agent is the default agent that is created when the program is started. Soar7 would search the current working directory for a file named "soar.soar"; if it existed then it would automatically be sourced. This is no longer the case. 2.2 Removed create-, destroy-, and select-interpreter Commands -------------------------------------------------------------- The commands for performing multi-agent actions are no longer supported. Instead, multiple agents are created by creating multiple Tcl interpreters using the interp create command, and loading Soar into each interpreter. Agents can communicate with one another using the existing Tcl inter-interpreter communication primitive: the "interp eval" command. The "create-interpreter" command has been superseded by the Tcl "interp create" command. Similarly, the "destroy-interpreter" command has been superseded by the Tcl "interp delete" command. The select-interpreter command is no longer available. Instead, agents should be addressed using the "interp eval" primitive. As an example, consider the following transcript: % interp create agent1 agent1 % agent1 eval { > package require Soar > init-soar > source $default > } 7.1.0 ************************************** % This sequence of commands creates a slave interpreter called "agent1", then evaluates a sequence of commands in that agent that require the Soar package, initialize Soar, and source the default productions. 2.4 Removed "interp_name" and "interp_type" Variables ----------------------------------------------------- The interp_name and interp_type variables no longer exist. If it is necessary for an interpreter to made aware of its own name, use code similar to the following: # Assume the interpreter we wish to create is named # by the variable "name" interp create $name $name eval "set interp_name $name" In this way, the interp_name variable is explicitly set within the agent. In Tcl terms, slave interpreters have no concept of "name" in relation to a master interpreter. 2.5 Run Command Works Only in Agent Interpreters ------------------------------------------------ The "run" command no longer is supported in non-agent interpreters; that is, interpreters that do not have the Soar package loaded. 2.6 Stopping a Soar Runaway on Windows and Macintosh ---------------------------------------------------- On UNIX, and in tclsh on Windows and Macintosh, Ctrl+C is interpreted as an operating system signal that halts a Soar "run" command in its tracks. On Windows and Macintosh, wish interprets Ctrl+C as an "accelerator key" (i.e., like selecting "Copy" from the "Edit" menu). This has the unfortunate effect of making unrestricted "run" commands unstoppable! There may be a way to translate accelerator keys in future versions of Tk which will resolve this problem. As an interim solution, there is a Tcl script in the Soar library called "console.tcl" that creates a Tk console for Soar with a "Stop Soar" button. Source this file with the following command: % source [file join $env(SOAR_LIBRARY) console.tcl] The "Stop Soar" button will appropriately halt the run command. 3. Upgrading Soar 7.0.4 Code to Soar 7.1 ======================================== This section describes a general guide for upgrading Soar 7.0.4 code to Soar 7.1. 3.1 Use Platform-Independent File Names --------------------------------------- Different platforms use different characters to separate directory names in files. Use the "file join" command to concatenate a directory with another directory or file name; for example, use: source [file join $env(SOAR_LIBRARY) console.tcl] rather than: source $env(SOAR_LIBRARY)/console.tcl The "file join" command is smart enough to deal with directories. For example, source [file join $MyUtilitiesDir graphics/widget6.tcl] works as expected on UNIX, Windows, and Macintosh. 3.2 Add "package require Soar" to Main Program Files ---------------------------------------------------- Most Soar systems consist of several Tcl scripts (".tcl" or ".soar" files), usually all sourced by a "main" file (e.g., "soar.soar"). Add the line: package require Soar To the start of this file. You can investigate the "package" command in the Tcl documentation if you feel you might want to require a specific version of Soar. (Currently, only 7.1.0 is implemented; however, this may be useful in later releases.) 3.3 Rewrite Multiagent Functions -------------------------------- A laundry list here: 1. Replace "create-interpreter" with "interp create". 2. Replace "destroy-interpreter" with "interp delete". 3. Replace "send $agent {...}" with "$agent eval {...}". Unfortunately, if you've embedded "select-interpreter" into your code, you may need to perform a fairly significant rewrite of some of your functions. That is beyond the scope of this document. 3.4 Issue "run" Commands to Agent Interpreters ---------------------------------------------- Some Tk programs have a wish console that handles "run" and "stop-soar" commands. Use the "$agent eval {...}" command to send these to an interpreter with an agent loaded. Alternatively, load Soar into the console interpreter and source the default productions (so that the agent always "waits"). This is somewhat wasteful, but works: package require Soar source $default watch 0 The "watch 0" command ensures that no output from the "waiting" Soar agent will be echoed to the console. 4. Known Bugs ============= Unfortunately, there are still some problems in the new release. 1. The schedule-interpreter command is not implemented properly. 2. Both tclsh and wish cause general protection faults on exit in Windows 95 and Windows NT. This is due to an incompatibility between the compiler with which the native Win32 Tcl & Tk binaries were compiled (Borland's) and the compiler used to compile the Soar dynamic library (Microsoft Visual C++). I've made a patch available on the Web that fixes the problem. 3. The Windows and Macintosh ports report minimal timing information; e.g., in commands like "stats". 4. The "log" command does not work properly. I have posted a message to comp.lang.tcl to see if there are any general-purpose solutions or packages that handle logging console input to a file. Similarly, it seems that some options for the "output-strings-destination" do not work, nor does the "command-to-file" command. 5. Implementation Details ========================= This section describes some of the implementation details that may affect users that have created complex Soar environments. 5.1 Signal Handling ------------------- To get signal handling to work properly just required making sure that init_soar got called: it actually installs the signal handler. I had moved the code into DllMain, which was nice, but there doesn't seem to be an equivalent initialization hook for dynamically loaded libraries. This still doesn't seem to work in wish42 on Window 95 (and probably NT). I'm not surprised, because it doesn't seem like any signal handling exists for the application (actually, Ibet that Ctrl+C gets translated as an accellerator key). 5.2 Printing ------------ To get printing to work right, I noticed that soarAgent.c initializes the print callback to the file stdout. I removed this, and added an additional call to "output-strings-destination -push -channel stdout" at the end of the agent initialization script which seems to fix the problem. 5.3 Setting Up the "soar_library" Variable ------------------------------------------ I added some intelligence to the routine that sets up the "soar_library" variable. Specifically, it works as follows: 1. If the SOAR_LIBRARY environment variable is set, it uses that variable's value for soar_library. 2. Otherwise, it will search each directory in the paths specified by the tcl_pkgPath and auto_path variables for a subdirectory called "soar". The first instance of a "soar" subdirectory it finds will be set to the soar_library. 3. The current working directory. This basically mimics the way that Tcl searches for packages, which seemed consistent and reasonable (at least to me). 5.4 Incompatible .lib's on Windows ---------------------------------- When compiling on Windows, I found that the library files that are distributed on the Sun Labs ftp site are out of date, and will crash tclsh and wish when you try to load the DLL you've built with them. To fix this, I had to create my own "tcl76.lib" file from the "tcl76.dll" distributed with Tcl 7.6p2. Here's how I did it: 1. Use "dumpbin.exe" to dump the exports: C:\> cd \windows\system C:\WINDOWS\System> dumpbin /exports tcl76.dll > \tmp\tcl76.def 2. Edit the file so that you get an "EXPORTS" statement for each function; for example, EXPORTS TclChdir EXPORTS TclCleanupChildren EXPORTS TclCloseFile EXPORTS TclClosePipeFile EXPORTS TclCopyAndCollapse EXPORTS TclCreateCommandChannel EXPORTS TclCreatePipe EXPORTS TclCreatePipeline (...and so forth) Basically, just used emacs to do some fance regexp replaces on the file. 3. Use "lib" to create an import library: C:\TMP> lib /machine:ix86 /def:tcl76.def C:\TMP> move tcl76.lib \msdev\lib That's all! 6. To Do ======== 1. Fix the "schedule-interpreter" command so that it works properly. 2. Examine alternatives for a "control panel" interpreter that would have access to the Soar "run" and "stop" commands (among others), but would not require an active agent.