"Making Sim_Agent more Usable and Transparent"

being a third year undergraduate project by

Mark Gemmell


Psychology and Artificial Intelligence

at the

School of Computer Science,

The University of Birmingham

and supervised by

Aaron Sloman


April 2002


Version 2

Table of Contents:

Title page - i

Including: title, author, degree, name of supervisor, date.

Preamble - ii

Including: table of contents, abstract, acknowledgments.

Introduction - 1

Including: project aims, motivation, wider context, specific goals.

Design - 5

Including: scenarios, project scope, ontology, behavioral specification.

High-level Implementation - 7

Including: functional divisions & representations.

Low-level Implementation - 10

Including: use of active variables, use of wrappers, building flexible panels.

Conclusions - 20

Including: unachieved goals, reflections on design, project management, appraisal, future developments.

Bibliography - 24

Including: online help files, websites, software libraries.

Appendices - 26

Including: I: minimum code; II: results data; III: full program code; IV: instructions for use; V: agent toolkit list; VI: objectclass hierarchy & slots.








This report summaries the work to make Sim_agent more usable. Sim_agent is an advanced agent toolkit, used for academic research, but rarely by undergraduate students. From a study in toolkits more generally, the qualities the make Sim_agent both powerful and hard to use are considered and a design drawn up to allow beginners to use Sim_agent without learning new syntax. This was achieved through allowing the user to specify the simulation parameters through use of graphical panels (using RCLIB, RC_CONTROL_PANEL). The interface utilizes many pre-existing software libraries on behalf of the user. A secondary feature, to allow the user to observe the internal state of agents while the simulation is running is also included, and its difficult implementation is discussed at length. The project as a whole is considered, and the initial designed reviewed with hindsight. Many possible future extensions are briefly discussed.




I would like to thank Aaron Sloman for his encouragement, and help in many areas, particularly the following:

Debugging interactions between interface and low-level systems.

Help with translating strings into pop-11 compliable code.

Pointing me to new concepts, programming techniques and help files required to do the job when I was otherwise at a loss.




In development for the past eight years and still evolving, with many contributors including former school members, PhD students, ex-HP labs researchers, but largely and most formidably, a man distinguished both as philosopher and a professor of Artificial Intelligence, is a very powerful, flexible, multi-paradigm system, used by many here, and at other universities on either side of the Atlantic, for research central to the AI dream – increasing our understanding human minds. However it is sadly under-used by the undergraduate student community, despite its availability and ample documentation. To consider why this is, and implement a solution was my project: making Sim_agent more usable and transparent.

I use the term "usable" to mean both the ability for novices to use the package and to gain expertise with it. By "transparent" I mean that the way it works should be easily deducible from using it. In a sense, I hope to achieve the same effect as in the physical world if all the coverings of an mechanical devise were made of glass, so one could see which cogs turned which, and what the consequences of it were, and so on, until one knew not just what it does, but has a reasonable idea of how, and the stages involved.

The motivation for this work, apart from the above, comes from a previous attempt to use Sim_agent myself, where my previous programming knowledge gained on the undergraduate course, and the relevant teach files, still left me very unsure how to go about using the package for the first time.

Another motivation, aside from the fact that I found difficulty in learning to use Sim_agent, is that, while others could learn it as I did, a consequence of that would be fewer people, especially undergraduates would use it at all. Sim_agent is a wonderfully powerful and flexible system, that once mastered can be used to great effect quite easily. I think it would be enjoyable and beneficial for students, should they overcome the usability problem. One of the chief reasons for this, is the flexibility it allows for exploring the aspect of A.I. you want to explore. Although not primarily designed for it, can be easily be used to investigate:

- condition-action rules

- sensory – motor systems

- artificial neural networks

- search

- games

- geometric problems (e.g. mazes)

- evolutionary simulations

- agent programming!

If the basic package used to learn these things is the same, that familiarity will aid getting to the underlying theory and studying it, cutting out time learning individual packages, or building low-level systems. Comparisons of one technique to another will be a natural benefit also, students would tend to think less in terms of different modules, and more in terms of Artificial Intelligence perhaps. While a specialised package would be needed to go deeply into some of these other areas of A.I. the initial (and for teaching purposes, vital) stage can be understood more easily within a common framework. There are many more advantages, such as the way it 'fits into' the POP-11 programming style which also makes it ideal for students. A desire to make these advantages accessible was another motivation for doing this work.



Sim_agent is an "agent toolkit". Agent toolkits are software for supporting "agents". The definition of a software agent is a somewhat controversial issue. But many people agree that they are software that exhibit at least some or all of the following characteristics1:

Autonomy, agents do not require constant human user intervention

Awareness, agents are aware of their environment and react to the changes in it

Persistence, agents function continuously for a period of time rather than performing an action and disappearing when it is done (i.e. an agent's work is never done :-) ).

Adaptiveness, agents adapt their behaviour over time and may learn to respond to the changes in the environment better.

Cooperation, agents are aware of and communicate with other agents to achieve their goals. Agent toolkits go about attempting to achieve the above in different manners.

But not all agent toolkits are alike! For example, while the "LPA Agent Toolkit" claims to achieve all the above, it constrains upon the user:

Agent architectures with a fixed long and short term goals system

Agents with beliefs encoded as Prolog facts.

Agents that cannot modify their (long-term) goals.

No easy way to extend the simulation to include graphics, ANNs, or other facilities.

A way of 'building' agents from pre-set, rigid, prolog predicates.

Sim_agent, by comparison utilises:

Object oriented programming (including generic functions and multiple inheritance).

Rule-based programming and pattern matching.

List processing

Event driven programming (e.g. handling mouse events, or new percepts)

Conventional procedural and functional programming

Other computational paradigms needed for particular applications, e.g. neural nets

Extendable syntax and semantics (macros and beyond)

Incremental compilation with dynamic replacement of modules

Automatic store management and garbage collection2.

Creating a very expressive tool to build complex agents rapidly. It is these qualities that make the package both attractive to the academic researcher, and hard to use initially to the undergraduate programmer.

Object-orientated programming is an obvious approach to take to an agent-toolkit. The abstraction afforded by the object-orientated approach (while possible without it) makes it easier to define objects in the simulation, by being allowed to program more directly in terms of objects, within the programming language. More powerfully, however, within the Objectclass system in POP-11, are not only benefits of data-encapsulation but also multiple-inheritance and generic functions.6

Multiple-inheritance allows a class to inherit the attributes directly from any number of other classes, which may be similar or completely different. For example, two agent classes, could be combined, to produce a third, which would have the attributes of both the original two. Less obvious, perhaps, is that an agent class could be combined with a class from the graphic library in POP-11, and so a class is produced that is both an agent, and also a 2D picture6. Working toward this end, is a software library, SIM_PICAGENT, that links graphical classes from RCLIB and classes from SIM_AGENT, allowing 'graphical agents' to be constructed fairly easily.

Generic functions allow the same procedure name to refer to different procedures, dependent on the class of the instance the generic function is operating upon. This extends the ability to give different objects different abilities, as each class of objects not only inherits different data slots, but also a different set of methods that can be applied to them.

The based rule programming and pattern matching is the system by which different behaviors of agents are triggered when certain conditions are true. This makes the system highly functional but hard to learn. There are syntaxes unique to specifying condition-action rules, unique syntax for the matching system, and also standard POP-11 code can be embedded into rules. This juxtaposition of interacting but different systems, gives power to the expert and nightmares to the novice.

The RCLIB extension is a more user-friendly tool, but it unfortunately does add another software library that "fits in somehow" with the rest. The difficulty is that there is more than one way that RCLIB can be incorporated, although the documentation does now point to using SIM_PICAGENT.

All of these difficulties for the user mean even that when a student does attempt to define a complete Sim_agent scenario, and finds a problem in his code, there will be so many confounding variables as to where the error, or more likely, errors, may lie, that it is simply beyond the student's ability to sort it out. One needs an exceptionally step-by-step tutorial file, that brings together these libraries, rather than containing references to six other files which deal with them independently.

SIM_HARNESS, is a software library that takes scenario data a in formal, organised format and setups up the scenario from there. While this aids the text-based user, it does nothing to move beyond a text-based approach. My project aims to provide a graphical interface to define a simulation, and to so in effect by being a graphical front-end for SIM_HARNESS. Although not designed with a graphical interface in mind, SIM_HARNESS does a fair amount of 'setting up' work, and is tried and tested software, and so I have decided to use it.


Another toolkit (there are hundreds, see Appendix V) "Zeus", shares some of Sim_agent's characteristics, especially rapid-prototyping and user extensibility. Also though, to its credit, it is "based on the 'visual programming' paradigm," to "support the agent creation process by providing structured menus and tables that would enable application developers to configure the functionality and modalities required of their agents as simply as possible."5 It is just such an approach as this that Sim_agent lacks, and leaves something of a mystery to the beginner as to get a simulation 'up and running.'

Zeus' 'visual programming' paradigm also includes a "A Control Tool that is used to remotely review and/or modify the internal states of individual agents," among other visualisation features. While ZEUS is perhaps less inclined towards modeling human minds for AI research, a feature like this I would consider invaluable to the Sim_agent package.

Zeus visualisation tool – showing agent architecture


All that is required to set up a very simple Sim_agent scenario, (not even a scenario really, just enough to show the package is really there) involves a reasonable amount of code, using many syntaxes new to the user, designed with new, novel, deep and sometime interacting concepts in mind. The amount of basic reading to gain an initial grasp of these areas would take days. (And possibly a lot longer to let the ideas 'settle'.) The code required is listed in Appendix I.

The tracing features of Sim_agent are very sophisticated in a text-based way, and quite daunting to the new user. This is partially because all the tracing names refer to when the tracing is called: all semi-familiar names that user doesn't yet have a solid framework within which to place them. Even when some of the tracing methods have been grasped, it prints out (often great volumes at great speeds) and the user usually has to review the code later, and relate it by memory to what was happening. There is an advantage in being able to review the tracing later, but for beginners, a way of seeing the tracing at the same time as the simulation, and a simple, easy way of pausing the simulation, editing it and carrying on would allow much greater control over early simulations when they are still learning the package.


The project aims "to make Sim_agent more usable and more transparent" are rather vague, and their success could only truly be measured in the long-term – is Sim_agent used more, and more easily? More specific and measurable goals are required for the scope of the project. These are as follows:

To devise a way of defining and running a Sim_agent scenario, such that an undergraduate would require as little extra learning as possible via documentation. Ideally, this would mean not learning any new syntax. This would be achieved by a program that allowed a user to construct classes and agents (and graphics) with a graphical interface instead of a text-editor.

To allow a way of interacting with Sim_agent during a simulation so as to enable modification of the agents, and viewing of their internal states while they are simulated. This also should rely on as little keyboard input as possible, and be of a graphical nature.




This section describes both what my program does, and what its was my intention for it do. Areas that have not been realised as I intended are note at the end of this section.

In the example in the previous section outlined the new concepts a novice would need to learn and the code that would need to be written in order to simulate a very simple scenario. My project scenario is based on allowing the user to achieve the same simulation with much greater ease. The scenario starts with the new interface already loaded, (just like an editor being loaded in the previous scenario).


A Main Menu appears, with introductory text. Following instructions in the tutorial file, the user does the following:


Actions from Main panel Actions from a sub-panel

Clicks on "Create Class" button. --- >

Clicks on "mobile" as opposed to "fixed"

Types a class name in the obvious field

< --- Clicks on "Make class"

Clicks on "Window Settings" button --- >

< --- Clicks on "Default Window" button

Clicks on "Create Entities" button --- >

Types "George" in field labeled "sim_name"

Types "basic_rulesystem" in field labeled "sim_rulesystem"

< --- Clicks on "Make Entity"

Clicks on "Run Simulation"

The user has to type in three names, and click eight buttons. The panels are informative, with help buttons to explain the functions and choices available at each stage. Initial use of the program is guided by a tutorial file. The chief aspect that should be obvious from the scenario is how more quickly this can be carried out then programming all the code, this is important because speed is a function of how simple it is do, and greater simplicity in setting up a scenario maybe the greatest factor in making Sim_agent more usable.

The panel based interface allows the user to construct entities with almost as much freedom as the text-based 'interface'. It is easy to define a class with any of the fundamental qualities developed in SIM_PICAGENT (without having to know about these or SIM_PICAGENT itself) and add to these basic characteristics, any number of user-defined slots, with user-defined default values. Classes can also be nominated as sub-classes of any other classes that the user has already defined.

Any class can be defined as 'panel' as opposed to 'standard'. This difference enables a special kind of dynamic tracing and interaction option for those entities while the simulation is running. This tracing consists of a panel that can be shown or hidden on command, displaying information pertaining to the agent in question. The information shown in the panel is updated live, as the agent changes state. For example, if the agent were to move within the simulation space, the numbers on the panel, labeled "sim_x" and "sim_y" would change accordingly.

Not only does this panel provide a tracing system, but also, in many cases it can be used to change the agent's state. If one were to change the information in the panel, perhaps this time, the number referring to the range at which the agent can sense other entities, this would effect the agent's state and if the number were a significant increase, it may start to sense entities that were previous not sensed. This in turn would show up in field of the panel tracing the "new_sense_data" slot, as new data would now be 'sensed' at every cycle.

In order to distinguish between different agents, the user can specify the shape, colour and size of entities' icons, and also a text-string to be printed alongside it. All the parameters of the graphical window in which the simulation is displayed can be modified through two simple panels. More than one window can be specified, and different agents can be assigned to different windows. At each stage help buttons are present to inform the user what the various decisions to be taken are, and which factors need to be considered.

Being largely an interface in nature, my project consists mostly of ways to specify the parameters and defining qualities of five major constituent parts of simulations, those being:

It also attempts to guide the student (the prospective user) to doing so correctly. This quality is quite implicit within the design of the interface. There are three main errors a student falls into, left to the text-based approach

  1. incorrect syntax
  2. incorrect specification (windows to small, class attributes inappropriate, etc)
  3. uncertain approach

The input accepted by the interface is largely mouse-based, with some text input required within certain fields which have first been selected with the mouse. The visible output is to represent the user's choice on the screen, either by making it visible (e.g. the word the user has just typed now fills a text field) or by moving onto a further, more appropriate interaction, now that certain decisions have been taken.

Further to defining the simulation data, the panel system should allow the user to review what has already been defined, modify it, or delete it and start over. This will generate a user-friendly feel, as mistakes can be remedied, a product of which is that user-experimentation is encouraged. Once simulation data (definitions of classes, entities, icons, etc.) has been specified, it may be saved, to be used again later, and built further.

Upon the user indicating that the simulation should now be run, the program collates all the user-specified data and starts the simulation.

Aspects of the design that have not been achieved (and are discussed in the conclusions) are these: the allowance of only appropriate input; ability to save & load classes and entities; providing choice of rule-systems; a tutorial file; all settings to have a default value.


High-level Implementation

My project can be broken down into these critical elements:

    1. Panels to allow user to define, review, scrap, save & load simulation parameters
    2. POP-11 code to implement those structures specified
    3. A system to display and edit simulation data during simulation

The following diagram illustrates at a high level how the different components of my project fit together and interact. The three areas considered above are represented as those boxed by blue, red, and purple lines respectively.

Upon compilation of the program code, the user is presented with the main panel. The program finds out what the user wants to do, in terms of i) loading, saving, defining or reviewing data and ii) data concerning windows, icons, classes, entities or rulesystems. This is achieved simply by the presentation of panels with clearly marked buttons corresponding to each sub-domain.

Once it is clear what is being done (loading, defining) to which elements of simulation information (windows, entities) more complex panels are presented through which the user specifies simulation parameters (size of window, name of entity) via one of many mechanisms provided by the software library "RC_CONTROL_PANEL" (i.e. Sliders or text-input fields, etc). Examples of panels are:

The nature of the panel system, one leading onto another, each with a logical series of choices, helps remove the problem faced by students of not knowing how to 'go about' defining a simulation. In the same stroke, the problem of learning several new forms of syntax disappears as well. The correct range or type of values that ought to be specified are taught to the user by limiting what input should be allowed. This can be in the form of a slider the range of which includes only sensible numbers for the width of a window; a help button, which will inform of issues needing consideration in making a decision, or a text-field that should only allow words that match one of those in a list of words known to be valid.

At some stage between the user specifying the simulation information, and that simulation occurring, the definitions of icons, class, entities, etc. need to be declared to the system. This can happen at two different times. It can either occur as a response to a specification panel being completed, or later, when the simulation is being set up. Due to restrictions already in place, entities must be 'created' during the latter stage. Classes are created once the appropriate button is clicked on a panel. The class creator declares the class the user has specified to the system, including the class name, the names of super-classes from which it inherits, and the data slots and default values that instances of the class will acquire. It also informs the database of the existence of this class, with all the above parameters.

I now consider this an error in design. Loading and saving class information would be far simpler if class creation were done later on, and also, a user may specify a class, then come to realise it was incorrect and scrap it, which is easier if at that stage only a representation of the class exists, i.e. only an entry in the database (which can easily be removed), rather than the class having been declared to the system (which cannot so easily be removed). The only tricky issue here would be to perform all the necessary checks as soon as the class was specified so as to avoid errors relating to it later when the simulation setup may be halted by bad class definitions.

The entity creator is required by the pre-existing SIM_HARNESS setup library, to declare instances of the classes the user has defined when the simulation is being setup to run. It is similar to the class creator in that it receives input data (the class name, location and slot values of the entity and the window the it is to be drawn in,) and returns the actual entity as a result (the class creator creating an actual class as a result).

The "Panel Tracing and Interaction" extension to Sim_agent, while having the same goals as the rest of my project, reflects the transparency rather more, while the usability is neither particularly improved nor impoverished. It is also stand-alone, and does not require any of the systems in place that the panel setup approach provides.

It works by having any entity inherit attributes from a pre-defined class which provides the necessary information to construct a panel representing that entity, not only does the information within this panel change to keep up with the changing data in the simulation, but allows the user to edit the data representation in the panel and thus change the actual data in the simulation.

The panel is constructed at the time it is first requested (by right-clicking the object in question). It can then subsequently be hidden or displayed by further right-clicks.


Lower-level Implementation

Although my project only runs to about 3000 lines of code in all, it is highly functional, and there are few simple procedures. Below I have described some of the most interesting code that was developed, usually requiring substantial learning of new programming concepts and the more 'inner workings' of POPLOG. Naturally therefore, most of these sections of code started with a difficulty or problem, their current state being the solution that was implemented.

The most difficult aspect of my project to program, (and perhaps the area that now works the most smoothly) is the panel tracing and interaction facility.

Declaring Active Variables for the Panel Tracing and Interaction extension

The panel that was to display the values of an agent's slots, (referred to as an agent's slotpanel) was to be a series of interactive text fields. These fields were to each have a label (representing the name of the slot) and a text value (representing the value of the slot). Not all slots within an agent are possible or useful to trace. (For a complete structured listing of all the slots a simple agent may have, see appendix VI.) The names of slots that I deemed should be traced therefore were stored in further slot, called "traceable_slots". An agent's slotpanel, then, would consist of a title referring to which agent it was associated with, and then one text field for every traceable_slot. Here is an example:

Every text field has an associated identifier, the value of which is the string shown in the field. In order to allow a change in the panel to affect the slot of the agent, some sort of trigger was necessary that could run code to update the agent as required. Active variables (described in HELP * ACTIVE_VARIABLES) seemed ideal:

"Active variables allow variables to store multiple values, and allow side effects to associated with the access or updating of a variable."

While it may have been possible to achieve the same result with properties or reactors, active variables appeared more powerful and flexible, and so a better choice, allowing the system to be extended more easily.

The procedure that generated the slotpanel ("setup_agent_slotpanel"), was required to declare many variables, the names of which the procedure would have to 'come up with' itself.

This was achieved using, i) the command "gensym", and ii) rather than using "vars" , which would require a hard-coded name, "ident_declare" was used which could take a variable holding a word (the word becoming the new variable's name).

The procedure "setup_agent_slotpanel", takes an agent as its argument. It would need to declare an active variable for every text-field in the slotpanel. There was difficulty in getting the active variables to remember their text-fields, instead they would take on a reference to the text-field that was most recently processed in the "setup_agent_slotpanel" procedure.

A solution was produced whereby the declaring and defining of the active variables took place in a separate procedure called from "setup_agent_slotpanel", terminating as soon as the active variable had been declared, thus creating a closure and 'freezing' the values of the local variables involved (those variables that referred to the correct text-field). This way, each active variable 'remembered' the value of the text-field it was associated with, and did not take on those of the next variable to be produced.


Now that "setup_agent_slotpanel", could churn out as many active variables as an agent had 'traceable_slots' and each one the identifier for the appropriate text-field in the agent's slotpanel, an error emerged. Although through lexical closure, each active variable referred to the correct slot and text-field, it's design job consisted of "updating the agent's slot with the value the user typed in the text field." The problem here was that the user would type a string into the text fields, for example

Sim_x : 56 (field with label "Sim_x", and user inputs "56")

But, if we could extract the data structure the user has typed, and assign it to the variable "val" we would get this:

isstring(val) =>

** <true>

Whereas the data structure that the agent's slot, Sim_x, requires, is such:

isinteger(val) =>

** <true>

An error was produced if the string the user typed into the panel was directly fed into the slot of the agent.

If it were always a case of needing integers when in fact we had strings, the conversion would be simple, however sometimes lists, words, vectors, were required, sometimes one nested within another. The solution required a conversion between the string, and the value POP-11 would give it, if that string were a from a program source file being compiled.

The solution is very complex in terms of the processing POP-11, but simple, in terms of the code required: one line.



-> slot(agent);

produced the error mentioned above:


-> slot(agent);

corrected that problem.

This line of code does what is required: "a conversion between the string, and that value that POP-11 would give it, if the string were from a program source file being compiled." It should be noted that (while, of course, my project is compelled to be written in POP-11, as Sim_agent is) this technique is only possible in A.I. languages with incremental compilation (POP-11, of course, being one), so that code can be compiled after run-time.


Declaring Wrappers for Panel Tracing and Interaction extension

The panel tracing system operated successfully in that a change in the panel successfully altered the appropriate slot of the appropriate agent. Yet this is only half of the design specification. There are two ways in which it would be possible to produce the second half of the slotpanel's functionality. To make sure that changes occurring within the agents during simulation resulting in immediate (more or less) updates of the panel, it could either involve the panel rigorously checking all its current values against those in the agent at the end of every simulation cycle, or find another method.

The former is grossly undesirable for two reasons. Firstly, there are changes that occur within a cycle, that would not be detected if the panel only updated at the end of every cycle (the fact his occurs is indicative an important design feature in Sim_agent (simulated parallelism) and a system which aims to make Sim_agent more transparent should not mask this). Secondly, it would be terribly inefficient.

The "other method" was to modify the procedures that are automatically created with a class definition. Such modifications are called wrappers. While it would appear a fairly standard requirement, to add to procedures that are declared automatically, there is little in the way of documentation on the subject, what there is (that is relevant) being tucked away in REF * OBJECTCLASS, which is quite technical and difficult to understand if you are not an experienced programmer.

The wrapper works by replacing (in a sense) the old method that was responsible for updating the value of a slot for a particular class. I say "in a sense" because the old (unwrapped) method can be called from the wrapper (and must be, if the slot is actually to be updated).

There was a problem because whatever extra code was included in the updater wrapper for the 'traceable_slots' of an agent, was executed when any slot by that name, in any object was updated. For example, if we wrapped the method that updated the slot "sim_name", every object (beit related to a tracing panel or not) would call this wrapper code when its "sim_name" slot was updated. In short, wrappers were specific to slot names, not to individual occurrences of slots in individual objects.

It was simple to overcome the wrapper code being misapplied to other objects that did not have a tracing panel, by including a test in the wrapper code to ensure the object was of the right type:

if ispanel_trace(obj) then;

and also, to make sure that if the object was the right type, its panel was built, (and hence ready for updating)

if ControlPanel(obj) /== undef then;

What was more of a challenge was enabling this wrapper that was general to a slot name to update the correct text-field of the panel that was linked to the agent whose slot was being updated. This was achieved by the use of two more slots in the definition of objects suitable for panel tracing. One, "ControlPanel" (mentioned above) held a pointer to the definition of that agent's tracing panel, and hence each agent's own panel could easily be referred to as:


Also, a second slot, "varnames" which is modified as the panel is first constructed to hold the information of which slot names, text-field labels and active variable names are related. The wrapper (called with the agent involved as an argument) (after checking the object is a panel_trace object, with a valid panel already built) consults the information in the "varnames" slot of that agent to see which text-field is related to the slot being updated, and then updates the panel stored in the slot "ControlPanel" of the agent. The code is simply:

;;; use the pattern matcher to find the field label that is in the same sublist as the ;;; name of the slot that is being updated. Assign the name of the field label to ;;; "fieldlabel"

;;; the "!" ensures this produces no Boolean, just instantiates ?variables.

varnames(agent) --> ! [ == [ == ^slot ?fieldlabel = ] == ] ;

;;; once the field associated with the slot is known, update that field with the new value

new_value -> rc_field_item_of_name(ControlPanel(agent), fieldlabel, 1);

But it wasn't that simple. As the wrappers were to be complied at the time was object's panel was first built, (from the procedure "setup_agent_slotpanel") the same problems (and solutions) of lexical closure occurred. Also, the inverse problem (much more easily dealt with) encountered when defining active variables was present here too. This time, a string value was needed to update the text-fields in the panel, but the value of the slot of the agent would not (save by chance) be a string. This was more easily remedied than before:

;;; a string representation for an object created by concatenating it

;;; with the empty string:

new_value >< nullstring -> new_string_value;

Another, more minor, (though still critical) problem was that once the active variables (which would update the agent's slots upon the user editing the panel) and the wrappers (which would update the panel upon the simulation altering the agent's slots), were both defined . . . . . . . . . . . there was a recursion problem. This was amended by having the wrapper check that the string it was about to replace in the panel was different from that it which was replacing it.

if not(new_string_value = rc_field_item_of_name(ControlPanel(a), fieldlabel, 1)) then;


Having devised a mechanism to automatically and correctly generate wrappers for the traceable slots of an agent, I found it was not possible to declare a wrapper for a slot that existed in a class due to it being inherited from a superclass. This restriction seemed odd and unnecessary.

When asking the designer of the objectclass system, Steve Leach, (formerly Steve Knight) about this 'feature' he replied:

"In my original conception of ObjectClass, this [wrapping inherited slots] would definitely have been supported. There is nothing problematic about inherited slots, their updaters, or wrappers."

But he added:

"although it [the objectclass system] was subsequently modified before being incorporated into Poplog."

He also suggested a solution to the problem, but I did not understand it. I decided therefore, rather than put time I didn't have into learning it, just to carry on with the solution I'd already implemented.

Whether or not to support the wrapping of inherited slots is an efficiency issue, and as it is, the doesn't not support it. When you consider that almost all classes used in Sim_agent simulations are descendants of "Sim_Object" (the basic, premier class defined in the Sim_agent library), and most of the vital slots are defined in "Sim_Object," the problem of not being able to wrap inherited slots becomes extreme.

The way around this problem was to declare the wrappers of those slots for the class Sim_Object. But it is complicated by the fact that although many important slots are derived from Sim_Object, by no means all important slots are. Any object in a Sim_agent simulation is almost certain to have slots inherited from Sim_Object, and also a variety of other classes.

I decided on a wrapper definition that initially assumed a slot to be (originally) in Sim_Object, and test it against a list of exceptions. There were not too many slots that were both i) exceptions and ii) useful for tracing. If a slot was to be found that was of this nature, the wrapper definition was altered accordingly, to produce a wrapper for the class in which the slot was (originally) defined.

An example of this procedure being called is:



** [define : wrapper updaterof sim_name ( new_value , a : sim_object ,

oldupdater ) ; oldupdater ( new_value , a ) ; lvars fieldlabel

; lvars new_string_value ; if ispanel_trace ( a ) and

ControlPanel ( a ) /== undef then varnames ( a ) --> ! [ ==

[ == sim_name ? fieldlabel = ] == ] ; new_value >< nullstring

-> new_string_value ; if not ( new_string_value =

rc_field_item_of_name ( ControlPanel ( a ) , fieldlabel , 1

) ) then new_string_value -> rc_field_item_of_name (

ControlPanel ( a ) , fieldlabel , 1 ) ; endif ; endif ;

enddefine ;]


;;; Or upon manual formatting of the output:

** [

define : wrapper updaterof sim_name (new_value, a:sim_object, oldupdater);

oldupdater (new_value, a);

lvars fieldlabel;

lvars new_string_value;

if ispanel_trace(a) and ControlPanel(a) /== undef then

varnames(a) --> ! [ == [ == sim_name ? fieldlabel = ] == ];

new_value >< nullstring -> new_string_value;

if not(new_string_value =

rc_field_item_of_name(ControlPanel(a), fieldlabel, 1) ) then

new_string_value ->

rc_field_item_of_name (ControlPanel(a), fieldlabel, 1);



enddefine ;


Another example is in Appendix II. The overall behavior of "setup_agent_slotpanel" that the active variables and wrappers afford is shown here.

"goodtester" is an agent, whom has inherited from "panel_trace". His control panel has not yet been setup:

varnames(goodtester) =>

** []


** undef


;;; panel appears on screen at this point

ControlPanel(goodtester) =>

** <window_obj Arthur 444 535 392 464 items: 14>

;;; limited panel description.

varnames(goodtester) ==>

** [[sim_name text1 sim_name1]

[sim_speed text2 sim_speed1]

[sim_cycle_limit text3 sim_cycle_limit1]

[sim_interval text4 sim_interval1]

[sim_status text5 sim_status1]

[sim_rulesystem text6 sim_rulesystem1]

[sim_sensors text7 sim_sensors1]

[sim_sensor_data text8 sim_sensor_data1]

[sim_actions text9 sim_actions1]

[sim_in_messages text10 sim_in_messages1]

[sim_out_messages text11 sim_out_messages1]

[sim_x text12 sim_x1]

[sim_y text13 sim_y1]]

;;; sublists of form:

;;; [^slot_name ^text_field_name ^active_variable_name]

;;; if we want to get the value of sim_name field, it could be done thus:

vars fieldname;

varnames(goodtester) --> ! [ == [ == sim_name ?fieldname = ] == ];

fieldname =>

** text1

;;; and so now we can access (or update) the value of the field

rc_field_item_of_name(ControlPanel(goodtester), "text1",1) =>

** Arthur



Linking the panel specification system to SIM_HARNESS

As my project was to 'feed in' to SIM_HARNESS, the simulation data would need to be organised into the particular format that SIM_HARNESS was setup to process. For the most part this was of trivial importance. The exception was that SIM_HARNESS was rigidly bound to process a list of entity specifications and a procedure, which when called with these specifications as arguments, would produce actual entities as a result. This is sensible, given SIM_HARNESS was a front-end designed for simulations defined by the text-based approach, where for different groups or classes of entities the user could easily write individual procedures that 'created' them - a different procedure, each tailored to the sorts of setting-up that different entities required.

For example, a group of entities that were objects that need to be placed randomly a setup procedure maybe:

define make_obstacle(specs) -> obstacle;

;;; create an standard instance of class

newobstacle() -> obstacle;

;;; add random jitter to locations

Random0(50) + x_loc(obstacle) -> x_loc(obstacle);

Random0(50) + y_loc(obstalce) -> y_loc(obstacle);



With the panel approach, the user cannot (and indeed, by design, should not have to) write a procedure to setup an object, for every different type of entity he / she wants. The solution was to write a general procedure that could create an object of any defined class, with values for its slots that the user has specified, and draw it in the specified window (or windows) at the correct location. Given this context, I think the code is fairly self –explanatory:

define general_creator(slot_and_specs_list, win) -> creation;

;;; declare local variables, and extract class name, and location

;;; from specs list, leaving rest of it in "specs"

lvars (classname, location, specs)= explode(slot_and_specs_list);

lvars classstring, agent, slot_and_spec, slot, spec, agentname;

;;; construct compilation string for declaring new class instance

'new' >< classname >< '()' -> classstring;

;;; compile it and store new instance in variable "agent"

pop11_compile(pdtolist(incharitem(stringin(classstring)))) -> agent;

;;; set slot values for those mentioned in specs;

for slot_and_spec in specs do;

explode(slot_and_spec) -> (slot, spec);

spec -> valof(slot)(agent);


;;; set location values

sim_set_coords(agent, location(1), location(2));

;;; let this agent be bound to a variable that is its name

sim_name(agent) -> agentname;

ident_declare(agentname, 0, 0);

agent -> valof(agentname);

;;; draw the agent in the window(s) specified

if islist(win) then;

rc_add_containers(agent, win);


rc_add_container(agent, win);


;;; make the agent the result!

agent -> creation;



Ideally, this procedure would take arguments along the lines of :

general_creator(classname, location, slotnames_and_slotvalues, win);

But the rigid nature by which SIM_HARNESS calls this procedure requires that the classname, location and slotnames_and_slotvalues arguments all be grouped together in one argument (and then later exploded!). This is not a flaw the design of SIM_HARNESS, it is simply the unfortunate consequence of linking two systems designed along different lines.


Creating Panels with No Fixed Definition

The user-interface, as mentioned, consists largely of graphical panels, offering choices and settings to be decided upon by the user, and often, subsequent panels to allow further choices, until, once all the necessary parameters have been specified, and the simulation kicks-off.

Generally speaking, these panels, once the basic predicates have been learned, are reasonably easy to construct, and although doubtless a knowledge of POP-11 facilitates understanding the syntax design, the RC_CONTROL_PANEL library, being very self-contained and well conceived, almost makes POP-11 familiarity unnecessary. This being the case, after spending large amounts of time constructing the first few panels, the rest were coded ever more easily.

That is true, at least, as concerns basic panels: panels with a fixed layout, with sliders, dials, radio buttons that do little more than alter the value of associated variables. My use of the RC_CONTROL_PANEL facility at times went far beyond this, so much so, its author, Aaron Sloman considers a rethink necessary in the ways RC_CONTROL_PANEL allows users to specify how panels are built.

One of the main difficulties when writing a procedure that will define and build a panel with many functions, is that there are three levels at which code is seen by the POP-11 system. Also, the way in which variables are read and understood varies at each level. This can make for many counter-intuitive errors and difficulties in debugging.

A good example, highlighting the details of some of these problems is how the panel through which the user specifies the slot values for entities, is constructed:

There are an infinite combination of possible slots that any entity could have, which the one procedure responsible for building the panel to represent those slots must cater for. It does this, therefore, by looking up in the database the class which the entity to be specified pertains to, and finds the list of extra slots that that class has.

I say "extra slots" because it already has a knowledge of all the 'standard slots' that one can expect every entity to have. Again, as with panel tracing, it is not possible nor sensible to allow the user to specify all slots, (for one thing, there are a huge number, see appendix VI), so "standard slots" is a collection of the most intuitively understandable, and those that should most concern the beginner (example of slots excluded, include: "rc_exit_hander" (the value of which is the procedure applied when the mouse leaves the windows – it is a lower level concern, and nothing to do with "agent programming"). Once all the slots that will be represented as text-fields are known, they are remembered for later.

For every slot which the user may define then, a suitable field (i.e. text or number based) is 'prepared' as a list, and left on the stack at a suitable point within the superlist defining the panel. Information from the database allows the visible field label to denote the slot name, and the initial value within the field to be the default value. (Having the default value already set greatly increases the speed and ease to define entities, as one doesn't have laborious insert all the values that are not changed from default.)

A trickier fact is that every field in the panel must store the value the user assigns to it (or the default value the user leaves unmodified) in a variable, whose name must be known by the program so that the value can be accessed and stored in the entity's definition (within the database). If there were only 'standard slots' that the user was defining, they could each be accompanied by standard identifiers, known by the program, but the user must be able to specify the value of slots that he/she has defined, and there is no knowing how many of those there shall be.

What we do know, however, is that no two slots can share the same name, and we know the names of all the slots, as they are stored within the class definition in the database. A formula therefore of declaring a variable for each field as needed, the variable name being: <slotname> + "ident" will result in a enough variables, of different names, all of which the system knows about (simply by checking the list of entity's slots and adding "ident" to the end of each name).


To demonstrate this, if a class has been defined with two extras slots using extra slots:

The panel produced when defining an entity of this class looks like this:

For the code that defined the text-fields for this panel, see Appendix II.


Unachieved Goals

Many of the panels allow text input of any description, where, say, only integers are appropriate, or words that match one of those in a list. By design, the system should check the input is appropriate, and reject invalid input, explaining the reasons to the user. One of the gross errors on this front is that one is allowed to attempt to start the simulation without all (or indeed any) information defined.

Entity representations are only 'turned into' actual entities just before the simulation starts. Classes on the other hand are created as soon as they have been specified. While there are advantages to doing it this way (mentioned earlier) it has the drawback that to load classes, not only means to update the database (to include the representations) but it means that those classes must also be declared to the system directly after loading them. If they are not, entities which pertain to those classes could not be created later on.

If sufficient checks were introduced, it maybe a better design to have classes declared just before the entities are created, (just before the simulation is about to start). As is stands, because of this complication, classes (and therefore entities) do not load correctly. This would be easy to correct, given a little time. As the ability to save and load simulation data was not the part of the project I was interested in (it has the least AI feel to it), there is no way currently of writing that information to a file, it is stored in variables, the names of which are declared by the user, and so work is only saved for the duration of that POPLOG session. This is mainly because I felt that all the learning required to efficiently get POP-11 to read and write save-files, etc. was not the best use of time as regards the project as a whole (there were plenty of other things required to learn!).

There is quite an issue concerning how the defining of rulesystems should be incorporated into the panel-based approach. As it was the least suited area of simulation-data I have not tackled it yet. A simple (but less "hands on" ) approach, would be to have a set (of say ten) rulesystems, gradually growing in complexity, which the user can choose from, by specifying different names in the "sim_rulesystem" slot for an entity.

The gradual increment in complexity can be incorporated into a tutorial file (as yet not written) that reveals the code of the rulesystems (or small, relevant parts thereof) which the student has greater ability to understand, having seen the behavior produced. A simple learning technique could then be applied whereby the student observes the behavior of the next most complicated rulesystem, and looking at the code for the first, attempts to modify and build the rulesystem for the second. This would avoid the more difficult approach of having the user specify rule-systems through panels, a possibility I will discuss later.

A seriously annoying flaw at the moment, is that once a definition has been defined, it cannot be modified , reviewed, or scrapped. The buttons on the main panel reflect my intention to amend this, but it has not yet been attempted. This is another reason, maybe, why classes should be declared later on (see above). Once 'guards' have been put on the text entry fields to prevent typing errors, it will become less of a problem, but still much needed.

A more sophisticated aid to some text-entry fields, would be to allow (via a right-click, perhaps) a list of all valid entries (where these run to an appropriately small number). Such an example would be the save name of data to load, or the icon name for an entity. That is another matter than needs addressing: it is not yet possible to (easily) back-paddle if one has started to define an entity, and yet has not already defined any icons to used. There should in such cases be a way of entering the icon editor and returning to the entity definition panel as it was, once an icon has been defined.

Also, a small set of pre-defined icons available would be an useful asset, and easy to provide.

Reflections on Design

Although I can envision a panel system that may allow the user to specify a rulesystem, having series text-fields where conditions can be typed and another for the corresponding actions, I don't think it really stands up to serious examination. The user would certainly have to learn from of the syntax in order to produce rulesystems of any quality, and even then it would reduce the heart of Sim_agent to little more than a toy, and one that would be hard to use. More than with any other simulation data, while defining a rule, you really want to be able to browse the other rules you've been defining, and maybe 'tinker' a little. This is where the text-based approach is at its strongest.

It may seem that if rulesystems (where the "agent programming" occurs) does not lend itself to the panel approach, why bother with the rest. On the contrary, I think that if all the other difficulties can be overcome through the panel approach, that can leave the beginner needing to learn one syntax, one new area of programming, and see the results, all the 'other stuff' being taken care of.

I don't think that panels have no part to play in helping the user rulesystems. I basic text editor could be opened in a window, to allow rulesets to be defined (as in VED), and allow panel manipulation of rulesets, rulefamilies and rulesystems are large entities. The issue of rulesystems certainly needs more thought.

Another problem is that rulesystems use methods (generic functions) to carry out operations upon objects. Methods, like ordinary POP-11 procedures, can only be defined using a text-editor (in all sanity). While a good library of standard pre-defined methods (for standard activities, such as sensing, moving, communicating), may be enough for the beginner, the limits will be frustrating, and in reducing the creative freedom of the user, the package may dissuade users rather than encourage them.


Project Management

Communication between my supervisor and myself has been excellent, a noted exception to this was a month in the first semester (roughly Oct 22 – Nov 22) where there was all but no communication. This was because there was all but no work taking place as regards the project, due to severe personal problems. A lot of communication did (as one would hope) take place at this time between myself and welfare tutors and student support staff, etc.

Bar the exception noted above, meetings with my tutor have varied from twice a week to bi-weekly, dependant on how problematic the work being undertook was; how much other work could be attempted if one line of work was blocked with problems; and also the availability of my tutor. Meetings with my supervisor have played a key role, one of the main reasons for this is his expertise with almost all the (higher-level) software I am using, and the difficult nature of some of it grasp, especially the interactions between them. Progress reports when meetings have not occurred, have been in the form of emails, which while taking no formal precedence, have communicated the errors, thoughts for future directions, or questions that were current.


The code that exists is robust. The high-level design of the panel interface is not fully realised, and so the "ease of use" it should provide cannot be experienced. The scenario for which it does work shows how easily more complex scenarios could be defined when the project is completed. The incomplete nature of the project means that it does not, in practice fulfill the design goals. For these reasons I must conclude the project is a successful failure. It shows the potential for allowing beginners to define classes, instances, graphics from a panel environment.

By using the panel approach, the user requires no knowledge SIM_HARNESS, SIM_PICAGENT, or RCLIB, and only a very basic understanding of basis of Objectclass, that would soon come with use of the package anyway. The workings of POPRULEBASE would be required in order to produce scenarios of merit, but this is achievable for the beginner once the other worries are out the way. The help buttons, presenting the right part of the right help file at the right time, also go a long way making the learning of Sim_agent a doable, step-by-step process.

I believe the range of programming techniques and learning that has gone into this project is a major achievement. There has been matters of human-computer interaction to consider, interactions between different systems, as well as all the techniques Sim_agent employs and must to be understood to greater extent in order to then attempt a program that eases a beginner into using them.

The innate difficulty (often unforeseen) of the project's domain, and the endeavor I have put into getting the code into a state the supports a working scenario has made me into twice the programmer I was before I started this project, this too, I believe speaks well of the overall quality of what has been done, especially as this was achieved done having lost a month's time in the first semester.

Future Developments

If I had had more time, I may have attempted, once finishing implementing everything from the initial design, features such as these:

I think this ultimately incomplete project shows the potential for such a system in complete form, and hopefully the necessary developments required to bring it to being of practical use for students can be realised.




On-line help files (from The University of Birmingham School of Computer Science system, (teach, help reference and library files readily accessible from ved &, xved, etc.))
























6) TEACH * OOP Author: Aaron Sloman




















Software libraries (libraries the program relies upon, as opposed to libraries, viewing the code of which, has aided me)

RCLIB (and many of its smaller sub-libraries (e.g. rc_linepic), most especially RC_CONTROL_PANEL).










Web-pages (those used significantly)

1) http://www.lpa.co.uk/atk_det.htm

2) http://www.cs.bham.ac.uk/~axs/cog_affect/sim_agent.html (author: Aaron Sloman)

3) http://www.agentbuilder.com/AgentTools/

4) http://www.cems.uwe.ac.uk/~rsmith/ECOMAS/agent_toolkit_list_(courtesy_of_bt).htm

5) (page 7)




Appendix I:

Code required to get a VERY basic, (but well-formed) Sim_agent simulation going: (alternatively, see file ~ug83mxg/project/mincode.p )

;;; Required code for EXCEPTIONALLY SIMPLE scenario

;;; The agent does NO thinking, no interacting with other agents,

;;; it simply moves through the simulation space, (rigidly, in one

;;; direction, at an unchanging speed) and this movement is reflected

;;; within a window on the screen

;;; There is a lot of tracing that is probably unwanted, however, it would

;;; take more code and understanding to turn it off, so it remains in this

;;; scenario.

;;; This scenario does not use SIM_HARNESS, as to do so would require rather

;;; a lot more code - for TRIVIAL scenarios as this, SIM_HARNESS complicates

;;; matters.

;;; The same simulation below could be achieved in less lines, by using

;;; 'simpler' techniques, but these techniques would be too burdensome if

;;; the scenario grew to any significant size. The code below is for a small

;;; scenario, but written still, as if Sim_agent has been learned properly.

;;; (to run, hit ENTER, type: "L1", hit RETURN)

;;; ("ENTER" being lower right on the keypad)

uses simlib;

uses newkit;

uses sim_agent;

uses prblib;

uses poprulebase;

uses rclib;

uses sim_picagent;

uses objectclass;


vars George;

vars basic_window =

rc_new_window_object("right", "top", 200, 200, true, 'Basic Window',



define :class basic_agent is sim_movable_agent;



define :rulesystem basic_rulesystem;

include: basic_rules


define :ruleset basic_rules;

RULE rule_1


[do move_agent 1 0]


define :method move_agent(a1:sim_agent, dx, dy);


rc_move_by(a1, dx, dy, true);



instance basic_agent;

sim_name = "George";

sim_rulesystem = basic_rulesystem;

rc_pic_strings = [COLOUR 'red' {-7 -5 'G'}];

rc_pic_lines = [COLOUR 'black' [[SQUARE {-8 8 16}]] ];

sim_x = 20;

sim_y = 20;

endinstance -> George;


vars all_agents = [^George];


basic_window -> rc_current_window_object;

vars each_agent;

for each_agent in all_agents do;

rc_add_container(each_agent, basic_window);


sim_scheduler(all_agents, 30);



Although the code may not look much to an experienced programmer, very little of it is understood unless the library from which it is taken is understood first. It has taken me his long to define a simulation so efficiently and smoothly.


Appendix II:


** [define : wrapper updaterof sim_name ( new_value , a : sim_object ,

oldupdater ) ; oldupdater ( new_value , a ) ; lvars fieldlabel

; lvars new_string_value ; if ispanel_trace ( a ) and

ControlPanel ( a ) /== undef then varnames ( a ) --> ! [ ==

[ == sim_name ? fieldlabel = ] == ] ; new_value >< nullstring

-> new_string_value ; if not ( new_string_value =

rc_field_item_of_name ( ControlPanel ( a ) , fieldlabel , 1

) ) then new_string_value -> rc_field_item_of_name (

ControlPanel ( a ) , fieldlabel , 1 ) ; endif ; endif ;

enddefine ;]


;;; Or upon manual formatting:

** [

define : wrapper updaterof sim_name (new_value, a:sim_object, oldupdater);

oldupdater (new_value, a);

lvars fieldlabel;

lvars new_string_value;

if ispanel_trace(a) and ControlPanel(a) /== undef then

varnames(a) --> ! [ == [ == sim_name ? fieldlabel = ] == ];

new_value >< nullstring -> new_string_value;

if not(new_string_value = rc_field_item_of_name(ControlPanel(a), fieldlabel, 1) ) then

new_string_value -> rc_field_item_of_name (ControlPanel(a), fieldlabel, 1);



enddefine ;





** [define : wrapper updaterof sim_in_messages ( new_value , a : sim_agent , oldupdater ) ;

oldupdater ( new_value , a ) ; lvars fieldlabel ; lvars new_string_value ; if

ispanel_trace ( a ) and ControlPanel ( a ) /== undef then varnames ( a ) --> ! [ ==

[ == sim_in_messages ? fieldlabel = ] == ] ; new_value >< nullstring -> new_string_value

; if not ( new_string_value = rc_field_item_of_name ( ControlPanel ( a ) , fieldlabel

, 1 ) ) then new_string_value -> rc_field_item_of_name ( ControlPanel ( a ) , fieldlabel

, 1 ) ; endif ; endif ; enddefine ;]


;;; Or upon manual formatting:


** [

define : wrapper updaterof sim_in_messages (new_value, a: sim_agent, oldupdater);

oldupdater(new_value, a);

lvars fieldlabel;

lvars new_string_value;

if ispanel_trace(a) and ControlPanel(a) /== undef then;

varnames ( a ) --> ! [ == [ == sim_in_messages ? fieldlabel = ] == ] ;

new_value >< nullstring -> new_string_value ;

if not (new_string_value = rc_field_item_of_name(ControlPanel(a), fieldlabel, 1) ) then

new_string_value -> rc_field_item_of_name(ControlPanel(a), fieldlabel, 1);








Code produce by to form part of the panel definition that allows user to specifies the slots values of entities:

** [[TEXTIN {label text1}

{margin 5}

{fieldbg chocolate1}

{ident student_nameident}

{align centre}

{labelcolour black}

{labelstring student_name: }

: "Mark"]

[TEXTIN {label text2}

{margin 5}

{fieldbg chocolate1}

{ident supervisor_nameident}

{align centre}

{labelcolour black}

{labelstring supervisor_name: }

: "Aaron"]

[TEXTIN {label text3}

{margin 5}

{fieldbg chocolate1}

{ident sim_nameident}

{align centre}

{labelcolour black}

{labelstring sim_name: }

: undef]

[TEXTIN {label text4}

{margin 5}

{fieldbg chocolate1}

{ident sim_speedident}

{align centre}

{labelcolour black}

{labelstring sim_speed: }

: 1]

[TEXTIN {label text5}

{margin 5}

{fieldbg chocolate1}

{ident sim_cycle_limitident}

{align centre}

{labelcolour black}

{labelstring sim_cycle_limit: }

: 1]

[TEXTIN {label text6}

{margin 5}

{fieldbg chocolate1}

{ident sim_statusident}

{align centre}

{labelcolour black}

{labelstring sim_status: }

: undef]

[TEXTIN {label text7}

{margin 5}

{fieldbg chocolate1}

{ident sim_sensorsident}

{align centre}

{labelcolour black}

{labelstring sim_sensors: }

: [{sim_sense_agent 20}]]

[TEXTIN {label text8}

{margin 5}

{fieldbg chocolate1}

{ident sim_sensor_dataident}

{align centre}

{labelcolour black}

{labelstring sim_sensor_data: }

: []]

[TEXTIN {label text9}

{margin 5}

{fieldbg chocolate1}

{ident sim_rulesystemident}

{align centre}

{labelcolour black}

{labelstring sim_rulesystem: }

: simple_rulesystem]]

;;; some tests:

student_nameident =>

** "Mark"

supervisor_nameident =>

** "Aaron"







Appendix III:

Full program code can be found at:


The files located there are







ignore any other files that may be there.



Appendix IV:

Instructions for use:

I have only used this program from within XVED, and so I recommend others to use XVED or VED.

Open the file


in the editor.

Compile that file. (ENTER L1 RETURN in ved)

A panel presents itself. To perform the simulation mentioned in the report, do the following:

compile file ENTER "L1"

move panels around as necessary by dragging on the title bar

Click "Define"

Click "Window settings"

Click "Use standard single window"

Click "Define"

Click "Class definitions"

Click "Mobile"

Click "Agent"

Click "Panel"

Click "Unrotatable"

Click empty box to right of "Class name"

Type "class1" hit ENTER


Click "Return to main panel."

Click "Define"

Click "Entity Icons"

Click on the red square (top right)

Click on the hollow circle (middle row, 4th from left)

Click on the largest solid black square (bottom right)

Click on empty box beneath "Type string here:"

Type "a1" hit ENTER

Click on empty box to right of "Icon's name:"

Type "icon1" hit ENTER

Click on "Make Icon"

Click on "Define"

Click on "Entity definitions"

Click on "class1"

Click on empty box to right of "sim_name"

Hit DEL five times

Type ""George"" (i.e. type George with double quotes)


Click on empty box to right of "Icon name"

Type "icon1"



Click on "* Run Simulation *"

Click on "RUN" (on the new panel in top left corner of screen)

;;; if it stops moving, click on "RUN" again

;;; if looks as if it will disappear of the edge, drag it back with the left mouse button

Things to try:

Right-clicking the red circle that moves.

Putting different numbers into sim_x and sim_y panel fields.

Defining two agents that can sense one another

Using the slot panel to increase the "sim_speed" of one, so it over takes the other.

Experiment generally.

Appendix V:

A list of agent toolkits found on the web3,4. This search was the fruit of searching or an hour from www.google.com , stopping when the majority of lists of toolkits contained no new names. They are included here simply to demonstrate how many agent toolkits there are out there. There are almost 100 shown here.

ABS Agent Building Shell

ADE Architecture type-based Development Environment

AdventNet Agent Toolkit (C edition)

AdventNet Agent Toolkit (Java edition)


Agent Factory Intelligent Agent System





Agent Building Shell (ABS)

Agent Studio agent toolkit

Agent Tcl transportable agent system

AgentBase Toolkit

AgentBuilder Toolkit


Agentx Agent Development Environment

Aglets Software Development Kit

ALFA Agent Toolkit

Architecture type-based Development Environment (ADE)

Ascape software framework

Atos SNMP Agent Toolkit

Bee-gent Multi-Agent Framework

BOND Distributed Object Multi-Agent System

CABLE Cooperative Agent Building Environment

Concordia mobile agent toolkit



D-Agents mobile agents

DECAF Agent Framework

DIET Decentralised Information Ecosystem Technologies

DirectIA SDK

Excalibur Adaptive Constraint-based Agents in Artificial Environments


GMDO Agent Toolkit



Gypsy mobile agent project

Hive software platform

IBM Agent Building Environment (ABE)

IGEN Cognitive Agent Toolkit

InfoSpiders Adaptive Distributed Information Agents [server appears to be down]

Intelligent Agent Factory

Intelligent Agent Library

ACK Intelligent Agents

JADE Java Agent Development Environment

JAFMAS Java-based Agent Framework for Multi-Agent Systems

JAM Agent Architecture

JATLite Java agent toolkit


JIAC: Java Intelligent Agents Componentware

Jumping Beans


Knowbot System software

LPA Agent Toolkit

MADKit multi-agent development kit

MAST Multi-Agent Systems Tool

Microsoft Agent toolkit (ahem)

Mobiware Middleware Toolkit



Multi-Agent Modeling Language (MAML)

MultiAgent Systems Tool (MAST)

MuCode (Minimal Mobile Code Toolkit for Java)

ETMANSYS TMN/FastBench Toolkit Technology

NetStepper agent development environment

Network Query Language



Open Agent Architecture (OAA)

Pathwalker agent-oriented library


Process agent-based framework


Repast Agent Framework

RETSINA reusable agent infrastructure

Sensible Agents

SIM_Agent Toolkit

Social Interaction Framework (SIF) multi-agent system toolkit

SodaBot software agent environment

Solstice TMN Agent Toolkit

SOMA (Secure and Open Mobile Agent)

Sonex IAD (Intelligent Agent Definition) Toolkit

Swarm multi-agent simulation


The BDIM Agent Toolkit

TLWonder Agent Toolkit

Topia Personal Agents

Trigon OM2000 Management Agent Toolkit

Tryllian ADK (Agent Development Kit)


UMPRS Agent Architecture

Universitaet Muenchen SNMP Agent Toolkit

University of Edinburgh Agent Toolkit 0.1

Vertel TMN ADE (Agent Development Environment)

VIA Versatile Intelligent Agents

Voyager mobile agents system

ZEUS Agent Building Toolkit

(A note to those interested: JESS, Mozart and Sim_Agent were found only once dispite looking at many lists each about 30 toolkits in length, CONGEN was not found at all)


Appendix VI:

(Slots and Objectclass heirachy for the class of agent that can have a slotpanel.)



/ \

/ \

is sim_movable_agent \

| \ is panel_trace

| \

| \ ControlPanel

| \ slotlist

| \ labelnames

| \ traceable_slots

| \

| \

| \

is sim_agent is sim_multiwin_mobile

/ | \

/ sim_in_messages | \

/ sim_out_messages | \

/ | \

/ | \

/ | \

is sim_object is sim_multiwin--- is rc_linepic_movable

/ \ |

sim_name / rc_pic_containers \ rc_oldx |

sim_component_root / rc_picx |\ rc_oldy |

sim_valof | rc_picy | \ |

sim_speed | sim_x | \______ |

sim_cycle_limit | sim_y | \ |

sim_interval | sim_oldx | is rc_linepic

sim_status | sim_oldy |

sim_data | | rc_picx

sim_shared_data | | rc_pixy

sim_rulesystem | is rc_selectable rc_pic_lines

sim_original_rulesystem | rc_pic_strings

sim_sensors | rc_mouse_limit

sim_sensor_data | rc_button_up_handlers

sim_actions | rc_button_down_handlers

sim_setup_done; | rc_drag_handlers

/ rc_move_handler

/ rc_entry_handler

/ rc_exit_hander

is rc_keysensitive





rc_rotatable_picsonly (could be used in panel_agents)

| \

is rc_rotatable is_rc_linepic_movavble

rc_axis (dealth with above)