Extending a Java Simulation System for Agent-Object-Relationship Simulation

Erweiterung eines Java Simulations Systems für Agent-Object-Relationship Simulation

Andreas Post

Prof. Dr.. Gerd Wagner

Thesis Supervisor 

Chair of Internet Technology Brandenburg University of Technology Cottbus

Evaluator:Prof. Dr. Gerd WagnerProf. Dr. Rolf Kraemer


1. Introduction
1.1. Related Work
1.1.1. Swarm
1.1.2. Repast
1.1.3. AbSim
2. Agent-Object-Relationship Simulation
2.1. Principles of Agent-Object-Relationship Modeling
2.2. Agent-Object-Relationship Metamodel
2.3. Formal Description of AOR Simulation Flow
3. AORSML - A Script Language for AOR Simulations
3.1. Comparing different Approaches for Simulation Specification
3.1.1. Using System Programming Languages
3.1.2. Defining Simulations using Script Languages
3.1.3. Declarative Simulation Specification
3.1.4. Conclusions
3.2. Extending and Improving ABSimML for AOR Simulation
3.3. Language Structure
3.3.1. Basic Structure
3.3.2. SimulationParameters
3.3.3. EntityTypes
3.3.4. InitialState
3.3.5. Rules
3.4. AORSML Schema
3.5. Modeling a Beer Game Simulation
3.5.1. The classical MIT Beer Game
3.5.2. Modeling the Beer Game as Agent-Object-Relationship Simulation
3.6. Introducing Advanced Language Extensions
3.6.1. Creating Sets
3.6.2. Creating Agents and Objects in a Running Simulation
3.6.3. Destroying Agents and Objects in a Running Simulation
3.6.4. Changing the State of a large Set of Entities
3.7. Extending the Beer Game Simulation with new Language Features
3.7.1. New and Adapted AOR Entity Types
3.7.2. Initial System State
3.7.3. Exogenous Event AppearingNode
3.7.4. Exogenous Event DisappearingNode
3.7.5. Perception Event ChangingDownStreamNode
3.7.6. Perception Event ChangingUpStreamNode
4. AOR-JSim - A Java Code Generator and Simulator for AOR Simulations
4.1. Analyzing the AbSim Java Simulation System
4.1.1. Analyzing the Structure of abobsim
4.1.2. Necessary Improvements and Extensions
4.2. Introduction to AOR-JSim
4.2.1. Simulator Workflow
4.2.2. Simulation System Overview
4.3. Creating an Enhanced User Interface
4.4. Java Code Generation
4.5. Running Simulations
4.5.1. Implementing a Special Class Loader
4.5.2. Simulation Flow
4.6. Creating Project Files
4.6.1. Relevant Project State Information
4.6.2. Project File Structure
4.7. Creating Structured Simulation Output
4.7.1. Introducing an Interface to collect Simulation Data
4.7.2. Creating an XML based Output File
4.7.3. Implementing an Easy-Plugging Logger Architecture
4.8. Implementing a Simulation Control Center
5. Creating a Statistic Center for Live Evaluationof Simulations in AOR-JSim
5.1. An Architecture for Collecting Values and Creating Charts
5.2. Creating Charts
5.2.1. Line Charts
5.2.2. Pie Charts
5.2.3. Bar Charts
5.3. Extension of AOR-JSim Project Files for Statistic Settings Support
6. Multithreading and Distributed Simulation
6.1. Introducing a Multithreaded AOR-JSim Version
6.1.1. Interactive Simulation
6.2. Distributed AOR Simulation
6.2.1. Distributing the Simulation
6.2.2. Communication Between Distributed Entities
7. Conclusion and Outlook
References
Glossary
A. Eidesstattliche Erklärung
B. The Classical Beer Game in AORSML
C. An Advanced Beer Game Version
D. AORSML Schema
E. XML Schema for Simulation Output Language

Abstract

This Master Thesis introduces a Java simulation system for Agent-Object-Relationship (AOR) Simulation. The simulation system is a Java software for generating and running AOR simulations. The software system generates executable Java code from a given simulation description script and compiles this code. These simulations can then be executed directly with the software by using an underlying AOR simulation library. This thesis also presents the simulation description language as well as a complete simulation example. Furthermore, this work presents an extension for live statistic creation at simulation runtime. Finally, this thesis investigates on the possibilities of multithreaded and distributed AOR simulations.

Diese Masterarbeit stellt ein Java Simulationssystem für Agent-Object-Relationship (AOR) Simulation vor. Das Simulationssystem ist eine in Java geschriebene Software für die Generierung und Ausführung von AOR Simulationen. An Hand eines Simulations- Beschreibungsskriptes generiert das Softwaresystem ausführbaren Java Code und kompiliert diesen im Anschluß direkt. Diese Simulationen können dann direkt mit dem Simulator ausgeführt werden, wobei eine AOR Simulations- Bibliothek genutzt wird. Die Simulations- Beschreibungssprache wird ebenso vorgestellt wie ein komplettes Simulationsbeispiel. Des Weiteren stellt diese Arbeit eine Erweiterung für die Erstellung von grafischen Statistiken zur Simulationszeit vor. Abschließend untersucht diese Arbeit die Möglichkeiten von AOR Simulationen mit mehreren Threads sowie verteilter AOR Simulation.

1. Introduction

Simulation is today an important means for research in a lot of areas. There are several reasons for simulating a real system. A flight simulator is used for training pilots before they control a real air plane. Other simulations are used to simulate processes that would take to long for observing them in real time. Another example is be the simulation of the drift of the earths tectonic plates. A further reason for using simulations instead of real systems are large social networks. Simulating human behavior or the behavior of large groups of people helps to understand phenomena. For such research areas it is advantageous to use simulation systems that can model independent acting units: agents. A simulation system may be specialized for one specific purpose or may just define a general framework. In the second case, this enables to model arbitrary simulations that use the given framework. To execute such models it is necessary to create a simulation system that can execute any possible model that is based on the given framework. This in turn requires some simulation language or basic library to model a certain simulation example. This Master Thesis introduces a simulation system that enables the automatic generation and execution of Agent-Object-Relationship simulations. This simulation system uses a special description language for such simulation that will also be introduced in this work. Furthermore, this thesis shows a way to evaluate simulations with the help of graphical statistics live at simulation runtime. Finally, the possibilities of multithreaded and distributed simulation are investigated.

This thesis starts with a description of Agent-Object-Relationship Simulation in Section 2, “Agent-Object-Relationship Simulation”. After this, Section 3, “AORSML - A Script Language for AOR Simulations” presents the simulation description language and an example simulation. After this section, the simulation system AOR-JSim gets introduced in detail in Section 4, “AOR-JSim - A Java Code Generator and Simulator for AOR Simulations”. The following section, Section 5, “Creating a Statistic Center for Live Evaluationof Simulations in AOR-JSim”, introduces a statistic center for creating charts of a running simulation that is integrated in the simulation system. Section 6, “Multithreading and Distributed Simulation” then investigates on the possibilities of multithreaded and distributed AOR simulations. Finally, Section 7, “Conclusion and Outlook” concludes the work and gives some outlook on possible future work.

1.1. Related Work

Agent based or agent oriented modeling and simulation is a research area with growing importance for a lot of different scientific fields. There are a lot of different applications for simulations with independent acting entities, i.e., agents. There are several research projects that deal with agent simulation. Some example projects will be introduced in the following sections. The first section will present the Swarm project. After this, Section 1.1.2, “Repast” introduces the Repast simulation toolkit. Finally, Section 1.1.3, “AbSim” gives an insight to the AbSim simulation system that is the basis for the simulation system introduced in this work.

1.1.1. Swarm

Swarm is a toolkit for multi-agent simulation. It was originally developed at the Santa Fe Institute and is now continued by the Swarm Development Group[1]. It consists of a set of libraries that can be used to implement and execute agent based simulation models. Currently there are versions of the Swarm package available in Objective C and Java. The Swarm libraries contain basic classes that must be implemented to create own agents as well as classes for simulation execution and tools for simulation evaluation. It uses an architecture of concurrent acting agents. An agent creates events and acts on received events. Several agents can be combined as a swarm. This means, a swarm is a collection of agents. It has a schedule of events of the agents it consists of. In Swarm it is possible to create several swarms of agents. A swarm in turn is also an agent in the simulation, this means, a swarm can consist of other swarms that may contain simple agents or again swarms. The behavior of all agents within a specific swarm defines the behavior of this swarm. With this architecture it is possible to create hierarchical simulation models. Thus, there is a large variety of possibilities of creating agent based simulations. But, for creating simulation it is necessary to extend existing base classes. This means, the developer needs programming knowledge either in Objective C or in Java. [Swarm96] [Swarm07]

1.1.2. Repast

Repast (Recursive Porus Agent Simulation Toolkit) is another project for modeling agent based simulations. The basic version was developed for Java, .NET and Python. That latest release that will briefly be introduced in the following is an extended version of these basic versions called Repast Simphony or short Repast S[2]. As Swarm, Repast S is also an open source toolkit for agent based modeling. The basic concepts of Repast are taken from the Swarm project. It also consists of a set of libraries with basic classes for simulation definition and classes for simulation execution and evaluation. Thus, there are classes that must be extended to create simulation objects. The Repast S toolkit comes with a graphical user interface that makes it possible to load, and run simulations. With this interface, users can add components to simulations and change simulation parameters before starting a specific simulation. The user interface also provides the opportunity of controlling simulation execution by adding control functionalities like pausing, stepping and stopping simulations. Finally, it introduces a graphical analysis of simulation parameters at simulation runtime as well as some graphical simulation visualization. Thus, Repast S not only offers a possibility to create agent based simulations, it also includes a user interface for complete simulation control and analysis. But as for Swarm, it is also necessary to implement simulations in a system programming language or at least Python scripting. Programming knowledge is therefore still necessary. [Repa06] [Repa07]

1.1.3. AbSim

The third example for agent based modeling projects is AbSim, the Agent Based Simulator. It was introduced by Wolf-Ulrich Raffel within the framework of his dissertation of agent based simulation [Raf05]. In contrast to the other two introduced agent modeling toolkits, AbSim provides a declarative language for specifying simulations: AbSimML. Thus, no programming knowledge is necessary to create agent based simulations with AbSim. But, the original version of the simulation system cannot work directly with files written in this language. Simulations must be modeled with the UML tool ArgoUML [ARGO07]. The idea was that developers can specify simulations with the help of a graphical tool. But, the output of ArgoUML is not AbSimML, thus it must first be transformed with XSLT to AbSimML. When transformed successfully, AbSim creates Java classes from the given XML, compiles it and finally runs the simulation. Thus, implementing any system programming language code is not necessary. This simulation system will be the base of the simulation language and simulation system that will be introduced in this work. The language as well as the simulation system, that includes source code generation and execution, will be revised and extended with a lot of new possibilities in agent based modeling and new functions in simulation execution and validation.

2. Agent-Object-Relationship Simulation

Agent-Object-Relationship Simulation belongs to the group of agent-based simulation systems. Agent-based simulation, sometimes also called multi agent simulation as in [Klue06] or agent-oriented simulation, is a special simulation approach. In agent-based simulation, the simulation system consists of a set of interacting agents plus a simulation environment in that all agents exist. Every agent is an independent unit in the simulation system that is able to act with other agents and with the simulation environment. Furthermore, agents can perceive things and influence other passive objects in the simulation. The simulation environment contains these passive objects and from the sight of one agent all other agents. In addition, the simulation environment simulates external simulation influences like weather situations that may have an impact on agents. Agent-based simulations are well suited for simulating social systems or supply chains. Every agent can represent one human actor and by creating large sets of free acting and interacting units, it can be possible to observe human behavior in larger networks or the influence of some persons behavior to the whole system. Thus, those simulations are more realistic for such scenarios. For more information on agent-based simulations see [Klue06].

This section introduces Agent-Object-Relationship Simulation and Modeling as a special form of agent-based simulation. It uses a well defined metamodel and simulation language that can also be executed directly with special simulation software systems. The first sub section, Section 2.1, “Principles of Agent-Object-Relationship Modeling”, explains the principles of AOR modeling. The following section then presents the underlying metamodel for AOR Modeling. These two sections will give an abbreviated introduction and explanation. For a complete description see [Wag03]. Finally, the formal simulation flow of AOR simulations is described in Section 2.3, “Formal Description of AOR Simulation Flow”.

2.1. Principles of Agent-Object-Relationship Modeling

Agent-Object-Relationship Modeling introduces a modeling approach that combines ontological principles of entity relationship (ER) modeling with an agent-based vocabulary. Entities in AOR are agents and objects as physical entities and events, actions and messages as relational entities. Agents are active entities, they interact with each other and the simulation environment. Objects on the other side are passive entities like a book. The modeling of AOR is based on ER modeling, this means, AOR entities are in special relationships to each other. The following are the main principles of AOR Modeling as introduced in [Wag03]:

  1. An information system must define entities that represent units of information that belong together in a specific domain. In Agent-Object-Relationship Modeling an entity is an agent, object, event, action or message.

  2. Entities are related to other entities.

  3. Entity types are used to classify entities in the information system.

  4. Properties are used to model characteristics of entity types. The set of values of all properties forms the state of a specific entity.

  5. Associations between entities are modeled with relationship types.

  6. There is an internal and external view to an agent. The external view includes all properties of an agent that can be viewed by other entities. The internal view represents inner beliefs of an agent and is not visible to other entities.

  7. Actions and events in AOR can be communicative or non-communicative. Action events are special events created by actions.

  8. Messages are a means to model asynchronous communication between agents. Sending a message is a communication act performed by some agent. Receiving a message is the perception of a communication event.

  9. Beyond sending and receiving messages, agents also perceives other events from the simulation environment and do actions that are not used for communication purposes. Furthermore, an agent can store reminders for future acting.

  10. The basic AOR concept distinguishes between three agent types: biological, artificial and institutional. Humans or animals are classes of biological agents, software agents and robots are modeled as artificial agents. Finally, institutional agents represent organizations or parts of an organization.

These principles form a well defined base for modeling agent-based simulations. The following section will go deeper into the modeling of AOR simulations by describing the metamodel in combination with a UML based visual syntax.

2.2. Agent-Object-Relationship Metamodel

To specify a language that can be used for the automatic creation of executable AOR Simulations, it is necessary to specify an abstract syntax. This is done with a metamodel of the AOR simulation. It defines all types and relations that are available. This is an important base for developing AOR models and simulation definitions. The diagrams in this section are taken from the AOR project web site [AOR07].

Agent-Object-Relationship Simulation distinguishes between entity types and entities. An EntityType is a base type like a class in a programming language. An Entity is a concrete instance of an EntityType. Figure 1, “Relationship between entity types and entities.” shows this relation between entity types and entities. Every entity type is derived from a Type. This also applies to data types. As mentioned before, an instance of an entity type is an Entity. Every Entity has an id attribute to distinguish different entities of the same type. The characteristics of an entity type are defined by a set of properties of a certain type like string, integer or any other type. Every Property has a name attribute. The value of a property is defined as a Slot of this Property. All values together form the current state of an entity.

Figure 1. Relationship between entity types and entities. Entities are instances of entity types. Every entity type has a set of properties. The respective entity defines slots that carry the value of a property.

Relationship between entity types and entities. Entities are instances of entity types. Every entity type has a set of properties. The respective entity defines slots that carry the value of a property.

The next diagram shown in Figure 2, “Types in Agent-Object-Relationship Modeling and Simulation” gives an overview over all entity types in AOR Simulation and their relationship to each other. Not all entity types can be used directly when developing a concrete simulation, because some types are basic types that have several derived types. For instance, AgentType and ObjectType are both derived from PhysicalObjectType. Instances of the entity type AgentType are also instances of a PhysicalObjectType but it is not possible to create a direct instance of PhysicalObjectType. The same applies to event types. There are several super types that embrace a lot of other event types. There are two main categories of events: environment events and internal events. Every specialized event is a sub type of one of these two types. Environment events are events that occur in the simulation environment and that can have effects on every entity within the environment. Examples types are ExogenousEventType, CausedEventType and also ActionEventType. Indeed, actions are taken from agents, but they take place in the simulation environment. Another agent can only perceive that some other agent has taken an action. This leads to the second main category: internal events. These events only affect one single agent, more precise the internal side of an agent. Examples of internal event types are PerceptionEventType and ReminderEventType. Another important entity type is the MessageType. Messages are used for agent communication. An instance of a MessageType contains information about the sender and receiver of the message and the actual message content. Within the simulation, messages are wrapped into special events. An outgoing message is wrapped by an OutMessageEventType. An incoming message is wrapped by a special perception called InMessageEventType.

Figure 2. Types in Agent-Object-Relationship Modeling and Simulation

Types in Agent-Object-Relationship Modeling and Simulation

The reaction of the environment within an AOR simulation is described with environment rules. Every environment rule is triggered by an environment event. If a specific rule applies to an event can depend on a condition that is defined for the rule. An rule can result in several new events, including caused environment events or perception events for agents. Finally, the state of agents and objects can be influenced by an environment rule. See Figure 3, “Metamodel of an environment rule.” for the metamodel of an AOR environment rule.

Figure 3. Metamodel of an environment rule.

Metamodel of an environment rule.

For defining the inner behavior of an agent it is necessary to specify agent rules. Figure 4, “Metamodel of an agent rule.” shows the AOR metamodel of an agent rule. Agent rules are triggered by internal events like a perception. It is also possible to define a condition for this kind of rule. Agent rules can result in multiple other events. Possible results are internal reminder events, actions or messages. As this kind of rule defines the behavior of one single agent, state effects will also only affect one agent or better the internal state of it.

Figure 4. Metamodel of an agent rule.

Metamodel of an agent rule.

2.3. Formal Description of AOR Simulation Flow

In Agent-Object-Relationship Simulation, the whole process of simulating a model can be described in a formal way. This formalization of the simulation flow has the advantage of a clear and unambiguous description. This is then the base for transforming the model and the simulation process into an executable simulation. The complete simulation flow includes the flow of one complete simulation step, the step of the environment simulator and the step of every agent simulator. The AOR simulation flow is based on the simulation process of agent-based simulation as shown in [Raf05]. The formal description starts with the definition of the state of the simulation system, the environment and all agents.

The current state S of the simulation system consists of the state of the environment SE, the state SA_Int of all internal agents, the set of all future events E and the current simulation time t. Therefore, the state of the simulation system S is a tuple (SE, SA_Int, E, t).

The environment simulator manages the state of the simulation environment including all object states SO and the external states of all agents SA_Ext. Together with the set of all future environment events EEnv and the current time of the environment tEnv, the environment state SE is the following tuple: (SA_Ext, SO, EEnv, tEnv). Every external agent state includes information that is available for the whole simulation environment. For every agent in a simulation there is an external and an internal representation. If there are n agents, there are also n external states and n internal states. The current state of all n external agents is the set SA_Ext = {A_Ext1, A_Ext2, ..., A_Extn} with A_Exti as the external state of the ith agent. The state of all m objects SO is the set of the current state of all objects: SO = {O1, O2, ..., Om} where Oi is the ith object in the set.

Besides the environment state in an AOR simulation, there is an agent simulator that manages every internal agent state. The state of an agent simulator SA_Int consists of the state of its internal agent A_Int, the set of future internal events EInt and the internal agent simulator time tInt. This can be represented by the tuple (A_Int, EInt, tInt). The set of future internal events consists of all received perceptions P, including received messages that are modeled as incoming message perceptions, and future internal time events EInt_t.

The whole simulation process of an AOR simulation consists of simulation steps of a fixed length Δt. In every step, the environment simulator starts simulating a new step, after this, every agent simulator simulates the new simulation step. The complete simulation flow for one simulation step can be divided into five different steps. To distinguish in the following description between simulation steps and one of the five substeps, the word cycle will be used now when speaking of the complete simulation step and step for one of the substeps. The following describes these steps:

  1. The environment simulator starts its new cycle after receiving new action events EA from all agent simulators from the previous cycle. These action events will be simulated in this environment simulator cycle. The environment simulator always has a set of resulting environment events EEnv and exogenous events EExo. Resulting environment events are results from previous cycles and have an occurrence time property when the event should occur. Exogenous events are periodic events that influence the simulation environment from outside the simulation system. Both sets may be empty and may contain events that will occur in a future simulation cycle. Therefore it is necessary to use only these resulting environment and exogenous events whose occurrence time to is not larger than the current simulation time t. The current environment events EEnv_Cur can be determined with the following function: EEnv_Cur = EEnv(to <= t) and the set of current exogenous events with the function EExo_Cur = EExo(to <= t). The overall set of current events is the union of all actions, current environment events and current exogenous events:

  2. In the second step, the environment simulator simulates every current event in the order of their occurrence time[3]. To simulate an event, there is a set of rules than can be applied to this event. If a rule applies may depend on the current state of the environment simulator, but it is also possible that a rule will always be applied. A rule can result in new environment events EEnv_Res, perceptions for agents PRes and effects on the state of the environment. Thus, a rule can be described as a function r that uses the triggering event ETrigger - a event from the set of current events ECur - and the current state of the environment SE that results in a rule result Res. The following shows the complete function:

    The result of every rule in turn is a tuple (PRes, EEnv_Res, SE') that contains as mentioned resulting perceptions for agents, resulting environment events and a new state of the environment simulator. The resulting environment events of every rule are added to the set of future resulting events. The resulting perceptions of every rule are added to a set of all resulting perceptions. This set contains new perceptions for all agents.

  3. The environment simulator sends all new perceptions in the third step to the agent simulators. To do this, the environment simulator must separate the set of all perceptions into sub sets for every agent. Thus, every agent simulator will only receive a set of perceptions for its own agent. Finally, after sending all perceptions, the environment simulator updates it's clock by adding the time interval for one simulation cycle to the current time: tE' = tE + Δt.

  4. Steps four and five are processed by every agent simulator. The fourth step is the agent simulators analog step to the first described step. Every agent simulator starts it's current cycle processing after receiving the set of new perceptions P from the environment simulator. The agent simulator holds a set of internal reminder events EInt from previous cycles. Furthermore, like the set of exogenous events of the environment simulator, also the agent simulator has a set of periodic occurring events EPer. As for the environment simulator, it is again necessary to determine, what events are relevant for the current simulation cycle. The current internal events can be determined with the following formula: EInt_Cur = EInt(to <=t) with to as the occurrence time of a specific event. For determining all current periodic time events, the formula is similar: EPer_Cur = EPer(to <= t). The set of all current events to simulate is now the union of all perceptions, current internal events and current periodic events as the following equation shows:

  5. In the second step of the agent simulator - the fifth overall step - all current events will be simulated. Like the simulation of environment events, also internal events are simulated by processing rules for them. An agent rule applies to exactly one internal event but there may be several rules for this event. The result of the rule depends on the triggering event for this rule ETrigger and the state of the internal agent of this simulator SA_Inti. The i stands for the ith internal agent. The result Res of an agent rule can be described by the following formula:

    Every agent rule can result in new actions ARes of this agent, new messages MRes[4] to send to other agents, new internal events EInt_Res and a new state of the agent SA_Inti'. Thus, an agent rule result is a tuple of the form (ARes, MRes, EInt_Res, SA_Inti'). The agent simulator collects all resulting actions, messages and events until all current events have been simulated. All resulting internal events are then added to the set of internal events. The set of all resulting actions and the set of all resulting messages is then send to the environment simulator. Finally, every agent simulator updates the internal agent time by adding the simulation cycle time interval to the current time value.

After all agent simulators have finished the current simulation step, the environment simulator starts a new simulation cycle.

3. AORSML - A Script Language for AOR Simulations

Agent-Object-Relationship simulations use a high-level declarative language to specify simulations. This language - AORSML - Agent-Object-Relationship Simulation Markup Language - can be processed directly with AOR-JSim, the simulation system introduced in this work, to create Java source code and execute it. It is an XML based language that uses an XML Schema definition to enable easy validating and parsing of AORSML documents. Using XML syntax also has the advantage that AORSML files can be created, edited and viewed with a lot of free software. Furthermore, by using XML as a basis, the language remains human readable. The language is based on AbSimML, the description language for Agent Based Simulations. To use it with AOR simulations, it was necessary to adapt it to the vocabulary and syntax of AOR. In addition to this, the language was extended to enable a lot more functionalities to make AOR more flexible for different purposes.

This section starts with a comparison of different programming approaches. In other simulation systems, a user needs to implement a set of classes for executing simulations. Section 3.1, “Comparing different Approaches for Simulation Specification” investigates on the pros and cons. The next two sections describe the structure of the simulation language as well as the necessary changes to extend AbSimML for Agent-Object-Relationship Simulation. As mentioned, AORSML uses an XML Schema for validation. This Schema gets introduced in Section 3.4, “AORSML Schema”. The following section, Section 3.5, “Modeling a Beer Game Simulation” describes the development of the Beer Game as example simulation. The last two sections show extensions to the simulation language and an extended Beer Game simulation using these new features.

3.1. Comparing Declarative and Programming Approaches for Simulation Specification

Simulation systems that only provide a basic structure of a simulation environment but no actual simulation, need some kind of simulation language, that developers must use to specify a certain simulation. There are different approaches on how to specify simulations. There are several simulation system where user have to use system programming languages like C++ or Java to specify simulations. Those systems usually offer a set of libraries that can be used to create own simulations. Section 3.1.1, “Using System Programming Languages” shows the advantages and disadvantages of this approach. A second possibility is to use scripting languages for specifying simulations. A prominent example is the network simulator ns-2 [NS2]. Section 3.1.2, “Defining Simulations using Script Languages” will explain this possibility. Finally, the declarative approach uses well defined declarative languages as for instance XML based languages like AORSML. These languages describe what will happen in a simulation but not how. For executing simulations defined in this way, it is necessary to transform the information included in the simulation description into a programming language that can be executed directly. But, this approach has a lot of advantages. Section 3.1.3, “Declarative Simulation Specification” will describe this approach that is also used here.

3.1.1. Using System Programming Languages

The first approach in creating simulations for a simulation system with just basic system structure is creating simulations by using system programming languages. This means, the simulation developer uses a programming language like C++ or Java to specify a certain simulation based on a given system. This approach is used by the Swarm simulation system [Swarm96] or Repast [Repa06] as two examples for agent based simulation systems. Both systems provide libraries with basic classes or interfaces that must be overwritten or implemented to define simulation entities and processes. There are several advantages but also some disadvantages of this approach. First of all, using system programming languages provides a large freedom of simulation creation to the developer. The simulation systems like Swarm or Repast offer libraries that already include all needed basic functionalities and all necessary classes. When creating simulations, developers can use and extend these classes to define a certain simulation. Besides this, developers can easily create and insert complex algorithms and data structures when needed. This may be the most important advantage. But there are also other advantages as explained in [Oust98]. System programming languages are typed. This means, the type of some parameter is definitely known at compile time. Compilers can use this information to generate specialized code with improved performance.

But, system programming languages have also disadvantages. Simulation developers must use a specific programming language and need special programming knowledge. This means, a simulation developer must also be a software engineer for the specific system programming language of the given simulation system. Another aspect is that through the possibility to create nearly arbitrary source files, it is also possible that a resulting simulation definition is not completely conform with the actual specification of the simulation system. It is also harder to check such source code for plausibility. Even if compiled successfully, it might not work correctly with the simulation system.

3.1.2. Defining Simulations using Script Languages

Some simulation systems use script languages for the creation of simulations. An example is the network simulator ns-2 where simulation scripts are written in OTcl, an object-oriented extension of the script language Tcl [NS2] [OTcl95][5]. The simulation system itself is based on C++. It offers a large set of libraries with common network elements and features. With the help of OTcl users can write scripts to create network simulations. Using script languages makes simulation definition development usually much easier, since developers don't need deeper programming knowledge. One single statement in a script language may often perform a set of different tasks, thus, scripts are usually much shorter and easier to read and write than the corresponding code in a system programming language [Oust98]. Another advantage of scripting languages is that they are usually interpreted. Thus, developers can easily and fast try things out without the need of re-compiling everything. Therefore, scripts are often used in computer games for defining or modifying game environments, e.g., maps, and game objects, e.g., opponents [GamesAI04].

But, when using scripts for a specific simulation system, it is often not possible to check if the script is correct and if all necessary elements are defined before runtime. When using system programming languages, using interfaces or abstract classes forces a developer to implement important parts. The declarative approach also has possibilities for checking simulation definitions before using them. Scripting languages are also usually typeless, often all variables are just strings and their real type simple depends on the usage. This in turn can lead to errors that will not be detected before runtime. Thus, scripts also have advantages and disadvantages.

3.1.3. Declarative Simulation Specification

The third approach examined here is a declarative approach. Here, a developer describes what should happen without the need to specify how this will be implemented. A declarative specification as used for Agent-Object-Relationship Simulation is based on a metamodel. Thus, there is a theoretical foundation for the simulation model that allows the usage of a high-declarative language on basis of XML. Such languages are very easy to write and read and a simulation developer does not need any programming knowledge to define a simulation scenario. Another advantage is the well defined structure. For instance, it is possible to specify the language structure with Document Type Definitions (DTD) or XML Schema definitions. XML Schema allows to define complex structures including the order and quantity of elements and their attributes. Such languages can be validated directly at creation time. This eliminates the most sources of errors even before the file will be used with a simulation system. This makes developing of simulation files pretty easy in contrast to use system programming languages or also scripting languages.

On the other hand, simulation creation possibilities are much more limited than with the other two approaches. It is not possible to extend an element of the language. This would always require extending the whole language. Also algorithms are harder, if not impossible to realize. But, the resulting simulation file will always be a valid simulation file in reference to the metamodel of the language.

3.1.4. Conclusions

As shown, all three approaches have advantages and disadvantages, but for the given simulation model of Agent-Object-Relationship Simulation, the declarative approach seems best suited. In AOR, the relation between agents and objects is defined by rules in the form of Trigger -> Result. Rules in turn are usually a declarative way of defining behavior between simulation entities. They define What should happen without the need to specify a certain implementation. This means, the underlying simulation system is interchangeable. This is also an important advantage, since it does not matter if the simulation system is for instance a local Java application or maybe a JavaScript webservice architecture. The simulation files will work for all implementations. Another good reason for the decision to use a declarative simulation specification language is that through separation of implementation and logic it is possible to test each part independent from the other [GamesAI04]. Finally, the declarative approach allows simulation development for a greater group of interested persons, since no programming knowledge is necessary.

3.2. Extending and Improving ABSimML for Agent-Object-Relationship Simulation

The simulation language AORSML is based on ABSimML. This language Agent Based Simulation Markup Language, can be used for defining agent based simulations. Agent-Object-Relationship Simulation is also an agent based simulations approach. But, AOR is based on a well defined metamodel. Therefore, the language must be adapted to the metamodel. Furthermore, there are several improvements in the language concerning the functionality and the usability. This will be explained in the following.

The adaption of the AOR metamodel to the simulation language required the renaming of most simulation entities. In ABSimML, all simulation entities are modeled as classes. In contrast, Agent-Object-Relationship modeling uses the entity type concept as known from entity relationship modeling. Thus, everything in an AOR simulation is an entity, this means an instance of a basic entity type. This includes physical objects like agents and objects as well as actions, messages, perceptions and non-action events. For this reason, the renaming is very important to reflect the metamodel in the simulation description language. For example, in AORSML all simulation types are defined under the element EntityTypes, the basic agent entity type is called AgentType or the entity type for exogenous events is named ExogenousEventType.

In both simulation models, ABSim and AORS - Agent-Object-Relationship Simulation, an agent gets defined with its external state and an internal or mental state. In ABSimML it is necessary to define explicitly two different agent elements, one for the external and one for the internal state. It is also necessary to define extra instances of an agent for the internal and external state. The next listing shows an extract of an ABSimML file with the definition of an agent's external and internal state. This division makes it harder to read the complete file since it assumes that there are two agents that are called Door. Furthermore, both agent elements have an attribute id what fortifies the assumption that these two are different agents. But, there are only two different states concerning the view from outside to an agent and the internal, mental view.

<agent name="Door" type="external">
  <attribute name="open" type="boolean">
    <defaultvalue>false</defaultvalue>
  </attribute>
  <attribute name="opening" type="boolean">
    <defaultvalue>false</defaultvalue>
  </attribute>
  <attribute name="closing" type="boolean">
    <defaultvalue>false</defaultvalue>
  </attribute>
  <attribute name="id" type="int"/>
</agent>
<agent name="Door" type="internal">
  <attribute name="open" type="boolean">
    <defaultvalue>false</defaultvalue>
  </attribute>
  <attribute name="id" type="int"/>
</agent>

In AORSML, there is only one element per agent. To differentiate between the external and internal states, agents have properties and self belief properties. Self belief properties are used to describe the mental state of the agent, this means what the agent beliefs of itself. The listing below shows the same agent as the agent above but this time written in AORSML. The definition is much more compact but includes the same information. As can be seen, there is no id property any longer. There is a simple reason for leaving this property out of the agent definition. Every physical object, i.e., agent or object, has an id by default. Thus, it is not necessary to explicitly define a property for it. This also has the advantage that simulation developers cannot forget to define an id.

<AgentType name="Door">
  <Property name="open" type="boolean" defaultvalue="false"/>
  <Property name="opening" type="boolean" defaultvalue="false"/>
  <Property name="closing" type="boolean" defaultvalue="false"/>
  <SelfBeliefProperty name="open" type="boolean" defaultvalue="false"/>
</AgentType>

As can be seen in the listing above, agents do not have attributes any longer but properties. In ABSimML, an agents and objects state gets defined with attributes. Event classes as well as actions and messages have parameters. For Agent-Object-Relationship Simulation, all physical objects, events, actions and messages are entity types. This also means that they all have a common base called EntityType. Every entity type in AOR can consist of a set of properties, there is no distinction in the naming between physical objects and events, actions and messages. Thus, there is only one element called Property to define properties. Another renaming was made for simulation parameters. In ABSimML, these parameters are called constant. But in fact, those variables define parameters for different simulation purposes. And is it not mandatory, that these parameters must be fixed. For this reason it seemed to be more precise to use Parameter elements for defining simulation characteristics.

Another structural change from ABSimML to AORSML has been done for several basic attributes of events, actions and messages. The listing below shows an action, a message and a perception written in ABSimML. To specify the acting entity of an action, there is a parameter actor_id. The same applies to the message class, with the sender_id and receiver_id and the perception with the id of the perceiving agent perceptor_id. All these parameters are mandatory and must always be defined for proper simulation execution. Furthermore, messages need the parameters duration and reliability and all events a parameter time.

<action actor="Door" name="ActionClose">
  <parameter name="actor_id" type="int"/>
</action>
<message name="MessageOpen" receiver="Door" sender="Sensor">
  <parameter name="sender_id" type="int"/>
  <parameter name="receiver_id" type="int"/>
  <parameter name="duration" type="double">
    <defaultvalue>10</defaultvalue>
  </parameter>
  <parameter name="reliability" type="double">
    <defaultvalue>1</defaultvalue>
  </parameter>
</message>
<perceptualevent name="PerceptionMotion" perceptor="Sensor">
  <parameter name="time" type="double"/>
  <parameter name="perceptor_id" type="int"/>
</perceptualevent>

As one can imagine when looking at the listing above, there are a lot of possibilities a simulation developer can write incorrect simulation files with ABSimML. There are a lot of mandatory parameters the developer must include. If one single parameter is missing, the whole simulation may be non-executable. But, all these parameters are basic parameters of the respective class. Thus, is is much better when they are automatically included and the developer doesn't needs to define them explicitly. The listing below shows the same three elements defined in AORSML. As can be seen, non of the mentioned basic parameters is included as Property. It is now only necessary to specify values for those properties when creating instances of one of these entity types.

<ActionEventType name="ActionClose" actorType="Door">
</ActionEventType>
<MessageType name="MessageOpen" receiver="Door" sender="Sensor">
</MessageType>
<PerceptionEventType name="PerceptionMotion" perceptor="Sensor">
</PerceptionEventType>

To define instances of entity types that should be available at simulation start, ABSimML uses an element called initialstate. The same element is also included in AORSML, only the starting characters of each word are in upper case as for all elements in AORSML. But, entity instance definition was also changed to support Agent-Object-Relationship Simulation. As mentioned before, in ABSimML there is an element for the external state of an agent and one element for the internal state. This also applies to the initial state definition of an agent as shown in the next listing.

<agentInstance instanceOf="Door" name="Door1" type="external">
  <attribute name="id">
    <value>1</value>
  </attribute>
  <attribute name="open">
    <value>true</value>
  </attribute>
</agentInstance>
<agentInstance instanceOf="Door" name="Door1" type="internal">
  <attribute name="id">
    <value>1</value>
  </attribute>
  <attribute name="open">
    <value>true</value>
  </attribute>
</agentInstance>

As for the definition of an agent type, also the definition of an instance of this type is only one element in AORSML. This means, the instance element contains the external state and the internal state of the agent. The next listing shows the corresponding agent instance defined in AORSML. As mentioned above, there is no id property that must be specified in the type definition. Every instance element for a physical object has an attribute to specify the id of the instance. Another difference in instance definition is the assigning of values for properties. Since the AOR metamodel knows property / slot tuples, there are Slot elements to set a starting value for a defined property. All other entities in AORSML also have Slot elements to set values for properties.

<AgentInstance instanceOf="Door" name="Door1" id="1">
  <Slot property="open" value="true"/>
  <SelfBeliefSlot selfBeliefProperty="open" value="true"/>
</AgentInstance>

The last example that shows the development of the simulation language for Agent-Object-Relationship Simulation is the definition of rules. The next two listings show the same rule first in ABSimML and then in AORSML.

<rule name="RuleActionClose1" type="envrule">
  <trigger name="ActionClose"/>
  <entity name="Door" type="agent">
    <statecondition>
      context RuleActionClose1 inv stateCondition : 
      self.e1.id = 1 and self.e1.open and not (self.e1.closing)
    </statecondition>
    <stateeffect>
      context RuleActionClose1 inv stateEffect :
      self.e1.closing = true
    </stateeffect>
  </entity>
  <resulting name="EventClosed" type="event">
    re1
    <condition>
      context RuleActionClose1 inv resultingeventcondition :
      self.re1.time = 'e.getTime()+DoorSystem.T_CLOSE'
    </condition>
  </resulting>
</rule>
<EnvironmentRule name="RuleActionClose1">
  <triggeringEventExpr>
    <AtomicEventExpr eventName="ActionClose" alias="actionClose"/>
  </triggeringEventExpr>
  <involvedPhysicalObject>
    <Agent type="Door" id="1" alias="door"/>
  </involvedPhysicalObject>
  <condition language="Java">
    door.open == true &amp;&amp; door.closing != true
  </condition>
  <resultingEventExpr>
    <AtomicEventExpr eventName="EventClosed" eventType="event">
      <PropertyValueSlot eventProperty="occurrenceTime" 
            valueExpression="actionClose.occurrenceTime + DoorSystem.T_CLOSE"/>
    </AtomicEventExpr>
  </resultingEventExpr>
  <stateEffects language="Java">
    <assign property="door.closing" valueExpression="true"/>
  </stateEffects>
</EnvironmentRule>

The first change that can be seen is the name of the element. Both simulation languages divide between environment rules and agent rules. While ABSimML uses an attribute to mark a rule, AORSML has the two separate elements EnvironmentRule and AgentRule. On the one side, this increases the clarity of the complete simulation script. On the other side it allows that both rule elements can contain different sub elements if necessary. While in ABSimML there are the elements trigger and resulting, AORSML uses more precise elements called triggeringEventExpr and resultingEventExpr. This makes clear, that all triggers of rules as well as all resulting elements are event entities. As can be seen in the first rule listing above, there is an element with name entity in ABSimML. This is used for specifying agents or objects that should be involved by the rule. Since also events, actions and messages are entities in AORS, a new element had to be included in AORSML rules. The new element is called involvedPhysicalObject. Another change in the rule language is the definition of conditions. As the listing above shows, the statecondition element in ABSimML has a direct relation to the involved entity. In AORSML it is possible that the condition for a rule consists of the state of several agents, objects and also the triggering event. Therefore, the element condition is not any longer within the element that specifies the involved physical object. It must also be mentioned, that it is possible in AORSML that several physical objects may be involved by a rule. For the same reason as for the rule condition, also the element for defining state effects is no longer within the involved physical object element. In AORSML, for agents and objects that are specified as involved, the state may change.

The examples in this section clearly showed what must be changed and extended to create Agent-Object-Relationship Simulations starting with ABSimML. There are also several improvements that enhance the structure, readability and error-proneness of the new language in comparison to the language for Agent-Based Simulations. The complete structure of the new language will now be explained in detail in the next section.

3.3. Language Structure

The following sub sections describe the structure of AORSML - the Agent-Object-Relationship Simulation Markup Language. To start Section 3.3.1, “Basic Structure” explains the basic structure of every AORSML document. The following sections then describe all elements that can be defined in an AORSML simulation file. The code listings in the following sections show only the structure of each element but no example. See Appendix B, The Classical Beer Game in AORSML for an example for using the language in practise.

3.3.1. Basic Structure

The definition of an AORSML simulation has three main parts. The definition of all simulation entities that may be available within a running simulation, including all physical object and all events is one big part. Another part is used for defining initial states for all entities that are needed from the beginning of the simulation. The third important part is the definition of behavior rules for agents and the environment. These three parts plus a part for some simulation parameters forms the basic structure of an AORSML file. The following listing shows this structure. Every simulation file has the root element AORSML that includes all other elements. The root element has several attributes specifying the namespace and the schema location. The last attribute defines the title of the simulation. The title attribute is required. It will be used to create the simulation main class and the package definition when creating Java files. There are four required sub elements, that must be defined in the shown order. Every of those four elements can also appear only once. The first element SimulationParameters can be used to define some basic parameters that might be necessary within a simulation. There are also some important parameters when executing simulations with AOR-JSim that will be defined under this element. Section 3.3.2, “SimulationParameters” shows how to define simulation parameters. The following section explains the declaration of simulation entities. After this, Section 3.3.4, “InitialState” explains the possibilities of creating instances of agents, objects and events. Finally, Section 3.3.5, “Rules” introduces elements to specify rules.

<?xml version="1.0" encoding="iso-8859-1"?>
<AORSML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns="http://aors.info"
        xsi:schemaLocation="http://aors.info aorsml.xsd" 
        title="...">
  <SimulationParameters>

  </SimulationParameters>
  <EntityTypes>

  </EntityTypes>
  <InitialState>

  </InitialState>
  <Rules>

  </Rules>
</AORSML>

3.3.2. SimulationParameters

The sub element SimulationParameters contains the definition of parameters that might be needed within a simulation. There are two different categories of parameters. First, they can be used to define special values in a simulation. For instance, this can be a standard delay of messages or any other standardized value. Thus, these parameters are constants within the generated source code and can be retrieved by every simulation class at every point in a simulation[6]. The second category of simulation parameters are attributes that influence the simulation execution. The following listing shows an example that defines parameters for this second category. The parameter cycleDuration must always be defined. It defines the duration of a simulation cycle in simulation time. The simulation time is only a user defined value to convert the internal simulator clock[7] to the specific time of the simulation domain. All other time values within a simulation file must then refer to this time domain. But, the value for cycleDuration is only a single numeric value, it does not specify the time unit. To do this, the parameter timeUnit can be used. For example, if a simulation run should be one hour in the simulation domain, cycleDuration must be set to 1 and timeUnit to hours. The next parameter stopTime defines a definite end point for the whole simulation. Usually a simulation runs until there are no more future events that must be simulated. To specify when such a simulation should end, this parameter must be set to the right time value. In the example below, the simulation would stop after 24 hours in simulation time, that is here the same as 24 simulation cycles. Finally, the cycleRealTimeDelay parameter defines the length of one simulation cycle in real time. For normal simulation execution this parameter can be omitted. See Section 6.1, “Introducing a Multithreaded AOR-JSim Version” for a usage example.

<SimulationParameters>
  <Parameter name="cycleDuration" type="int" value="1"/>
  <Parameter name="timeUnit" type="String" value="hours"/>
  <Parameter name="stopTime" type="int" value="24"/>
  <Parameter name="cycleRealTimeDelay" type="long" value="1000"/>
</SimulationParameters>

3.3.3. EntityTypes

The EntityTypes sub element defines all entities that are needed within the simulation. Every entity must inherit from one of the basic AOR entity types. This includes the acting agents, passive objects and all events and messages that are necessary for running the simulation. The EntityTypes element contains the following entities:

  • Physical Objects

    • AgentType

    • ObjectType

  • Events

    • ActionEventType

    • CausedEventType

    • PerceptionSignalEventType

    • ExogenousEventType

    • PerceptionEventType

    • ReminderEventType

    • PeriodicTimeEventType

  • Messages

    • MessageType

These elements will now be explained in detail in the following sub sections.

3.3.3.1. AgentType

An agent is an active entity in the simulation. It can perceive its environment and react on it. An agent performs actions, sends messages to other agents and reacts on perceptions, incoming messages and special internal events. The entity AgentType has an attribute name for the name of the agent and the Java class that will be created from this definition. The AgentType entity can have several Property and SelfBeliefProperty elements. Both define properties of an agent. The Property element should be used for all properties that can be visible to the whole simulation environment. Properties that only the agent should know about, must be defined with the second type. These properties are also used for inner beliefs of the agent. This means an agent can belief that some of his properties have a specific value, but in fact they have some other value. Thus, it is also possible to define a property twice: as "normal" and as self belief property. Imagine a role player that moves across a digital world. The player agent might just have a rough knowledge about his position while the environment knows his exact coordinates. Both elements have three attributes: the property name and type and a defaultvalue. The first two attributes are required, the defaultvalue attribute is optional. The listing below shows the structure of an AgentType entity definition.

<AgentType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
  <SelfBeliefProperty name="..." type="..." defaultvalue="..."/>
</AgentType>
3.3.3.2. ObjectType

The ObjectType entity defines a passive object in the simulation. An object cannot act and cannot perceive anything. But objects can hold information for agents. For instance, an object could be a traffic node in a simulation where agents can move across roads. The traffic node object could hold information on possible ways or maybe some speed limit or something else.

The node itself wouldn't be able to act, but it's information would influence the behavior of agents. An object can also be goods in a trading simulation, for example. Objects have one attribute specifying the name of the object and an arbitrary number of properties. Every property must define the name of it and the type and optionally a default value. This value will be set automatically if no value gets defined for this property in an instance declaration of the object.

<Object name="...">
  <Property name="..." type="..." defaultvalue="..."/>
</Object>
3.3.3.3. ActionEventType

Agents interact with the simulation environment and other agents by taking actions. Actions are the result of an agent rule and get processed from the environment simulator. To define and action, the entity type ActionEventType must be used. The action event element has an attribute specifying the name of the entity and an attribute for declaring the type of agent that can do this action. Both attributes are required. Within this element, several Property elements can be specified. It is necessary to define the name and type of a property and optionally a default value. See the listing below for an example of an ActionEventType.

<ActionEventType name="..." actorType="...">
  <Property name="..." type="..." defaultvalue="..."/>
</ActionEventType>
3.3.3.4. CausedEventType

Caused events are special environment events that are the result and also the trigger of environment rules. They can result from actions, exogenous events or even another caused event. Caused events can for instance be used to create a time delay between an incoming event and the actual resulting event or resulting state effects. The element CausedEventType has only one attribute for the name of the entity. But, as can be seen in the following listing, it is also possible to define properties.

<CausedEventType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
</CausedEventType>
3.3.3.5. PerceptionSignalEventType

Perception signal events inherit from caused events. Thus, they are also the result and trigger of environment rules. They are used to create a delay for a perception event that an agent should perceive later in the simulation. For example, if agent 1 sends goods to agent 2 and it should be a delay between the taken send action and the perception of the receiving of the goods, a perception signal event can be used. In principle, caused events and perception signal events can be used for exactly the same purposes. The difference is the meaning of the event itself. Perception signal events should always be used if they should result in a perception event. Caused events may be used if the they should result in other environment events or effects on the state of agents and objects. The structure of the PerceptionSignalEventType entity is therefore identical with the CausedEventType element.

<PerceptionSignalEventType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
</PerceptionSignalEventType>
3.3.3.6. ExogenousEventType

Exogenous events represent events that occur outside the simulation environment but have effects inside the environment. A very simple example would be a sailing sports simulation. Every sail boat will be navigated by an agent. In a sailing simulation the wind would have a strong influence on the course of a boat. But, the wind speed and direction cannot be influenced by anyone inside the simulation. Here, it would be necessary to model these wind effects as exogenous events, that occur periodic or random periodic and influence agents within the simulation area. Thus, exogenous events have no cause[8] but can influence agents, objects or even the whole simulation. For an ExogenousEventType element there are two required sub elements: periodicity and stopCondition. Both elements have an attribute for the used language. The periodicity element defines the interval between two occurrences of the same event. In the example shown below it is a fixed value of 1[9]. When used with the Java simulation system, it is also possible to use random values. The simulation package includes a class with a set of static methods for generating different random values. The stopCondition element defines the condition till when to create new instances of this event. Without this declaration there will always be another occurring instance of this event. The occurrenceTime variable in the example below is a standard property of every event. It can be accessed when needed in any computation or comparison.

<ExogenousEventType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
  <periodicity language="Java">1</periodicity>
  <stopCondition language="Java">occurrenceTime &gt; 24</stopCondition>
</ExogenousEventType>
3.3.3.7. PerceptionEventType

Environment rules can result in special perception events that are used when an agent perceives something that occurred in the simulation. The PerceptionEventType element has two required attributes, the name of the perception event entity and the entity name of the agent type that perceives the event. Besides this, it is also possible to define properties.

<PerceptionEventType name="..." perceptor="...">
  <Property name="..." type="..." defaultvalue="..."/>
</PerceptionEventType>
3.3.3.8. ReminderEventType

A reminder event is an internal event of an agent. It can be the result and the trigger of agent rules. As the name suggests, reminder events can be used to let an agent remind itself to do something in the future. It can also be used to create a delay for something. Thus, it can be seen as the agents pendant to the environments caused events. The next listing shows the structure of the ReminderEventType element. The name again is a required attribute and it can contain Property elements.

<ReminderEventType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
</ReminderEventType>
3.3.3.9. PeriodicTimeEventType

Periodic time events are internal agent events that occur in periodic or random periodic intervals. The definition of the PeriodicTimeEventType element is similar to ExogenousEventType element, thus, it is also necessary to define the elements periodicity and stopCondition. Besides these two required elements, they can have Property elements.

<PeriodicTimeEventType name="...">
  <Property name="..." type="..." defaultvalue="..."/>
  <periodicity language="Java">...</periodicity>
  <stopCondition language="Java">...</stopCondition>
</PeriodicTimeEventType>
3.3.3.10. MessageType

Finally there are messages that can be defined. Messages are used for the communication between agents. The simulator uses special events to wrap the messages, but the message itself is not an event. Messages have three attributes, the name of the message class and the entity names of the receiver and the sender. Messages can define properties like all entities.

<MessageType name="..." receiver="..." sender="...">
  <Property name="..." type="int" defaultvalue="..."/>
</MessageType>

3.3.4. InitialState

The sub element InitialState defines the start state of the simulation system. This includes the concrete entities of the entity types that are defined under EntityTypes. It is hereby necessary to define entities that should be available at the start of the simulation. For instance, it is necessary to define all agent instances that will be available from the beginning but not any event that will be created as a rule result. For defining an instance of a declared type, at least the individual name and - in case of physical objects - the id must be specified. Furthermore, it is possible to set values for every property of an entity[10]. The following sections now show how to create instances of entity types. The first section introduces the definition of an initial agent state. Section 3.3.4.2, “ObjectInstance” shows how this will be done with objects. Finally, Section 3.3.4.3, “EventInstance” presents the structure for an initial event state definition.

3.3.4.1. AgentInstance

For every agent in a certain simulation, it is necessary to define the initial state. An instance must always refer to an agent entity type that was defined under EntityTypes. The following listing shows the structure of an agent instance definition. The AgentInstance element has three required attributes: instanceOf, name and id. The first identifies the type of the agent entity. The second is the name of the instance to be used in the generated Java code. The id attribute defines an identifier for the agent. Agents of the same type must have unique identifiers, but if the type differs, the id can be the same[11]. The AgentInstance element allows three sub elements: Slot, SelfBeliefSlot and EventInstance. Slots are used to assign initial values to external agent properties. The Slot element has an attribute that specifies the property that will be assigned and the value for the property. It is not required to assign a value for every property. Since agents can have self belief properties, there is also a special element for this assignment: SelfBeliefSlot. The usage is the same, but the attribute property is called selfBeliefProperty here. The third element EventInstance is used to define all internal events of an agent that should be available from the simulation start. For example, this is necessary for all periodic time events of an agent. An event instance has the attributes stereotype, instanceOf and name. The first defines the category of the event. The instanceOf attribute is used to assign the entity type of the event and the name attribute specifies the class name of the entity. Internal events must also define the two properties agentID and agentType. In addition, a periodic time event must define a value for the startingTime[12] property, specifying the first occurrence of the event. If the event has custom properties, it is possible to define values for them with the Slot element.

<AgentInstance instanceOf="..." name="..." id="...">
  <Slot property="..." value="..."/>
  <SelfBeliefSlot selfBeliefProperty="..." value="..."/>
  <EventInstance stereotype="..." instanceOf="..." name="...">
    <Slot property="startingTime" value="..."/>
    <Slot property="agentType" value="..."/>
    <Slot property="agentID" value="..."/>
  </EventInstance>
</AgentInstance>
3.3.4.2. ObjectInstance

To create instances of defined object entity types, the element ObjectInstance must be used. The following listing shows the basic structure. The ObjectInstance element has the same three attributes as defined for an agent instance. When defining values for properties, the Slot element must be used as can be seen in the example.

<ObjectInstance instanceOf="..." name="..." id="...">
  <Slot property="..." value="..."/>
</ObjectInstance>
3.3.4.3. EventInstance

To create instances of environment event entity types, the EventInstance element must be used. Usually, it is only necessary to create instances of exogenous events for the initial simulation state, since they cannot be instantiated later in a simulation. Environment events can later only be created as the result of a rule, but exogenous events cannot be the result of another event. See Section 3.3.3.6, “ExogenousEventType” for a complete description of exogenous events. It is also possible but not common to create instances of caused events. Since caused events are only resulting events, this feature may only be used for special purposes like special startup conditions. The listing below shows the initial state definition of two events. In addition to the attributes instanceOf and name, it is also required to define the attribute stereotype. This specifies the type of event. Possible values are: ExogenousEvent or CausedEvent. As for AgentInstance and ObjectInstance elements, the element EventInstance can also contain Slot elements to assign initial values to properties of the event entity type. It is mandatory to assign a value for the properties occurrenceTime in case of a caused event and startingTime in case of an exogenous event. The reason is that the time specifies when the event should occur. The startingTime property is only a special name for the occurrenceTime property for periodic appearing events and specifies the first occurrence of it.

<EventInstance stereotype="..." instanceOf="..." name="...">
  <Slot property="occurrenceTime" value="..."/>
  <Slot property="..." value="..."/>
</EventInstance>
<EventInstance stereotype="ExogenousEventType" instanceOf="..." name="...">
  <Slot property="startingTime" value="1"/>
  <Slot property="..." value="..."/>
</EventInstance>

3.3.5. Rules

Rules are used to describe the behavior of agents and the reaction of the environment in a simulation. Rules are triggered by incoming events and can create new events as results as well as influencing the state of agents and objects. There are two different rule types in AOR simulation. Environment rules describe the reaction of the environment to actions and other environment events. Agent rules on the other side describe the behavior of agents. In the basic version of the language, there are no differences in the rule structure except the name of the wrapping element: EnvironmentRule or AgentRule. See Section 3.6, “Introducing Advanced Language Extensions” for extensions to the basic language. There are required and optional elements in a rule definition. The following elements are possible, elements with an * are hereby optional:

  • triggeringEventExpr

  • involvedPhysicalObject*

  • condition*

  • resultingEventExpr*

  • stateEffects*

As can be seen, it is theoretically possible to define a rule with just a triggering event. In deed, the resulting rule would be usable, but sure, this doesn't makes any sense. The first three elements are the declaration and condition part of a rule. The last two elements are used to create the result of a rule. This may be some resulting events or a change in the state of the simulation system. The first element triggeringEventExpr defines the trigger of the rule[13]. It has one sub element AtomicEventExpr that defines the name and an alias for the event. The eventName must be the same as the name declaration of the same event as defined under EntityTypes. The alias attribute has a special meaning for programming language processing. When creating a rule object, this object receives an instance of the triggering event and tries to get instances of all involved physical objects from the simulation system. Every of these instances can be accessed within methods of the rule. It is also possible to access an events, agents or objects property when creating resulting events or changing the state of physical objects. The underlying simulation processor - here a Java simulation system - must define identifiers, i.e., names, for using the objects. It could be possible that, when creating the rule source code, these names are automatically created like event, agent01, agent02 or something else. This approach is error-prone. When writing a simulation file, the user must always know when wanting to access a property, what identifier must be used. For instance, if the property property is needed from the second defined object, the user had to write object02.property. Such restrictions can easily lead to faulty simulation files. Moreover, the XML language would then depend on the actual implementation. Thus, a second way was chosen. The simulation writer simply chooses an identifying name - the alias attribute - and the simulation system is then forced to use this identifier. For instance, if a user chooses agent as alias, she then has to type agent.property when trying to access a property. Thus, using entities and their properties remains independent from the used simulation system.

After defining a trigger for the rule, it is possible to declare physical objects that are involved by the rule processing. In an agent rule it is necessary to define the agent type that is affected by the rule. There will be no id attribute, since the only agent that received the event and processes the rule can be affected by it. An environment rule on the other side can influence all external agent states and all object states. Here, the id attribute is required to access the right physical object. Again, the alias attribute is important to distinguish between all defined agents, objects and the triggering event. The next element, condition, can be used to define constraints under which the rule should apply. This can be constraints to the current state of the simulation system or simply a constraint to the value of a property of the trigger. This closes the declaration and condition part of the rule. The result part starts with the element resultingEventExpr. This element allows to declare multiple resulting events. The AtomicEventExpr element is again used here. The eventType attribute is used here to distinguish between different event families. This is necessary, since an environment rule can have resulting events for agents or resulting environment events for future processing. An agent rule can also result in future internal events and actions or messages that are send to the environment simulator for processing. The following values are possible:

event

future event for the environment simulator

perception

resulting perception event in an environment rule

action

resulting action in an agent rule

message

resulting message in an agent rule

reminderevent

resulting internal event in an agent rule

The last element in a rule is used for changing the state of involved physical objects. The stateEffects element allows an unlimited number of assign sub elements. The assign element has two attributes to specify what value should be assigned to what property. The property attribute defines the property of an agent or object that will be changed. As mentioned above, the name of the specific agent, object or event to use for accessing a property must be set with the alias attribute. To set a value for a property it is possible to assign a single value or a complex value expression. Thus, it is also possible to set a value like a+b*c.

<...Rule name="...">
  <triggeringEventExpr>
    <AtomicEventExpr eventName="..." alias="..."/>
  </triggeringEventExpr>
  <involvedPhysicalObject>
    <Agent type="..." alias="..." id="..."/>
    ...
    <Object type="..." alias="..." id="..."/>
    ...
  </involvedPhysicalObject>
  <condition language="Java">...</condition>
  <resultingEventExpr>
    <AtomicEventExpr eventName="..." eventType="...">
      <PropertyValueSlot eventProperty="..." valueExpression="..."/>
    </AtomicEventExpr>
    ...
  </resultingEventExpr>
  <stateEffects language="Java">
    <assign property="..." valueExpression="..."/>
    ...
  </stateEffects>
</...Rule>

3.4. AORSML Schema

An important improvement to the given AbSimML was the creation of an XML Schema definition for the new language. An XML Schema fully describes the structure of an XML document. Different from Document Type Definitions (DTD), XML Schema files are also based on XML. They also allow a lot more data types as DTDs. An XML Schema describes the complete structure of every element in an XML file including child elements and attributes. It is possible to define the order and frequency of sub elements. The necessity of attributes can be specified and it is also possible to limit attribute values to a set of possibilities. Due to this precise structural description, it is possible to validate XML files against a given Schema file. This eliminates the most possible sources of errors and ensures that a valid file will work with the simulator[14], since AOR-JSim validates every simulation file after opening.

Since an XML Schema is also an XML file, it has the typical XML structure. Schema definitions start as every XML document with a declaration followed by the root element. For XML Schema files, the root element is xs:schema that can include attributes for different namespace definitions and other settings. The root element must contain definitions for all elements of the target language. Defining child elements is possible in two different ways. One possibility is to define a child element directly under its father element. The other possibility is to use references for elements. As can be seen in the listing below, the AORSML Schema only uses references for the definition of the structure of an element. There are two reasons for this decision. First, there may be a lot of child elements with other child elements a.s.o. If all child elements are defined directly under their father element, this will reduce the readability of the schema file. In deed, using references as shown below, only shows the first subsequent layer of an element, but the main structure is much easier to understand. Another reason of this way of creating a schema is that all elements can be used several times. In AORSML there are multiple elements that use the same child elements. Thus, to avoid redundancy, every element will only be defined once and at any place it is needed, a reference to it will be inserted. The two elements AORSML and Rules use another important schema feature. The element AORSML has a complex type with a sequence of child elements. This defines that the four permitted child elements must be used in the shown order. Furthermore every of these elements must occur exactly once as specified with the attributes minOccurs and maxOccurs. Another possible complexType definition is used for the element Rules. The choice element specifies that the sequence and amount of the child elements is loose. Another interesting construct is shown in the element definition of AtomicEventExpr. The element has an attribute definition with a restriction to possible values of the attribute. The attribute eventType is hereby defined as simpleType with a string based restriction element. Only a value that is included in the enumeration wrapped by restriction can be used as a value for eventType.

<xs:schema xmlns="http://aors.info" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://aors.info" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">
  <xs:element name="AORSML">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="SimulationParameters" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="EntityTypes" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="InitialState" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="Rules" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="title" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  ...
  <xs:element name="Rules">
    <xs:complexType>
      <xs:choice minOccurs="1" maxOccurs="unbounded">
        <xs:element ref="EnvironmentRule" 
                    minOccurs="1" maxOccurs="unbounded"/>
        <xs:element ref="AgentRule" minOccurs="1" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  ...
  <xs:element name="AtomicEventExpr">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="PropertyValueSlot" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="eventName" use="required"/>
      <xs:attribute name="eventType">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="event"/>
            <xs:enumeration value="perception"/>
            <xs:enumeration value="action"/>
            <xs:enumeration value="reminderevent"/>
            <xs:enumeration value="message"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="alias"/>
    </xs:complexType>
  </xs:element>
  ...
</xs:schema>

The complete schema definition is shown in Appendix D, AORSML Schema.

3.5. Modeling a Beer Game Simulation

For extending the simulator to Agent-Object-Relationship Simulation including creating the AOR simulation language, it is necessary to create a sample simulation. A very simple but also illustrative simulation example is the Beer Game. It is easy to understand but, as will be shown in the following, uses most elements of Agent-Object-Relationship Simulation. The following sections will demonstrate how to model this simulation in AORSML.

3.5.1. The classical MIT Beer Game

The Beer Game is a classical management simulation. It was developed in the 1960s at the Sloan School of Management of the Massachusetts Institute of Technology [Beer04]. The game is played by four players. Each player is a node in a beer supply chain that consists of a Retailer, Wholesaler, Distributor and a Factory. Every player has an inventory with some amount of beer. A player orders beer from the player that is one place up in the supply chain and ships beer to the player that is one place down the chain. Due to the fact that an order takes one simulation cycle but the delivery two weeks, there are usually interesting behaviors to observe. The results of this simulation will not be of interest here, anyway, as will be shown in the following, this simply simulation is well suited to develop the simulation language.

Figure 5, “The Beer Game supply chain.” shows the basic structure of the Beer Game. All four supply chain nodes have nearly the same behavior. They have to manage their stock of beer and their amount of beer orders from the node one place down the chain. When receiving a beer order, a node has to ship the desired amount immediately if its stock is high enough. If a node has not enough beer to satisfy all needs, the node must send its complete amount of beer and memorize the remaining quantity. After this, a node can order new beer from the node one place up in the supply chain. The ordered quantity can hereby be a fixed value, e.g., 10 per round, a random value or a computed value depending on the lack of beer[15]. Finally, every node computes the costs of the current round and adds the result to the value of overall costs. Costs incurred include the current stock of beer and the quantity of beer that was ordered by another node and could not be shipped in the current round. Thus, simply ordering large amounts of beer to satisfy all needs in every round won't be a good decision as well as ordering small amounts to keep the stock low. Only a strategy between both extremes will lead to a minimum of costs.

The first and the last supply chain node have some special characteristics to mention. Since, the retailer node has no node in downstream direction, the node would have no one to receive orders from and no one to ship beer to. For this reason, there is a fictive customer that orders and receives beer. The customer must be simulated somehow from the simulation system that controls the Beer Game. The same applies to the factory node. There is no node in upstream direction, thus the simulation system must also control the part of receiving raw materials orders and the shipping of raw materials. The next section shows how the Beer Game is modeled with AORSML.

Figure 5. The Beer Game supply chain.

The Beer Game supply chain.

3.5.2. Modeling the Beer Game as Agent-Object-Relationship Simulation

This section now shows how to model the Beer Game simulation as an Agent-Object-Relationship simulation. The simulation description will be textual. See Appendix B, The Classical Beer Game in AORSML for the AORSML script of the Beer Game described in the following. This section is divided into several sub sections. The first sections shows an AOR model of the game. After this, the following section identities the corresponding AORSML entity types. Then, Section 3.5.2.3, “Initial System State” introduces the initial state of the Beer Game simulation. The following sections then show the simulation processes within the game.

3.5.2.1. An AOR Model of the Beer Game

This section shows how to model the Beer Game as Agent-Object-Relationship Simulation. This is the first step in creating a simulation file in AORSML. There is only one type of agent necessary in the Beer Game: the SupplyChainNode. All agents in the simulation are instances of this entity type. As described in Section 3.5.1, “The classical MIT Beer Game”, the interaction between two nodes consists of sending / receiving beer orders and shipping / receiving beer. Figure 6, “Interaction frame between two nodes in the supply chain as external AOR diagram.” shows this interaction as an external AOR diagram. Every node sends messages of type Order to the next node in upstream direction. The message has the quantity of beer to order as property. As additional information, the delay of the messages receiving at the next node is 7 days. This information is important for running the model within any simulation system. In downstream direction, every node does the action event ShipBeer. This event also has a property specifying the shipped quantity of beer. This action will be perceived from the next node down the chain as the non-action event BeerDelivery. Between the shipping action and the delivery perception, there will also be a delay. As defined for the Beer Game, this delay is twice as long as sending an order, thus, in this model it will be 14 days.

Figure 6. Interaction frame between two nodes in the supply chain as external AOR diagram.

Interaction frame between two nodes in the supply chain as external AOR diagram.

Every node in the supply chain has several reaction rules that are used to define the behavior of the node. Figure 7, “Internal AOR model of a SupplyChainNode.” shows the basic set of reaction rules[16]. This first rule R1 applies in case a message of type Order is received by the agent. This will increase the currentSalesOrderQuantity property of the agent by the quantity property of the message. There is nothing else to do in this case. Rule R2 applies when an agent perceives the non-action event BeerDelivery. This perception is used to inform a node about a new beer delivery, thus, the inventory property of the agent will be increased by the quantity property of the BeerDelivery perception. The third rule R3 is used when the agent perceives the non-action event EndOfWeek. This event causes several things. First, the node does a ShipBeer action event to ship ordered beer to another agent. In this simplified example, the agent will always ship the whole amount of ordered beer. In a complete model it would be necessary to distinguish between the case, the agent has enough beer in stock or not. The next result of the reaction rule is the creation of a new outgoing message to order new beer from the next agent in upstream direction. The value of the quantity property of the message may be fixed or some random value. Finally, after shipping beer and ordering new beer, the state of the SupplyChainNode agent will change. The inventory property will be decremented by the amount of shipped beer. In this simplified example, all orders have been shipped, thus, the sum of all orders will be subtracted from the inventory property. Then, properties currentSalesOrderQuantity and backorderQuantity are set 0. Finally, the costs of the node will be calculated. In this example, the costs property would always be 0. But in a real simulation of the Beer Game, nodes will not always be able to ship all orders or might have to much beer in stock.

Figure 7. Internal AOR model of a SupplyChainNode.

Internal AOR model of a SupplyChainNode.

The first node in the Beer Game supply chain, the Retailer node, has some special characteristics. Since this node is the lowest in the chain, there is no node in downstream direction that sends orders to this node or that can receive beer from this node. The Retailer node itself can be an instance of a SupplyChainNode agent, but there must be other reaction rules to define the behavior. To receive orders, there must be a non-action event created from the environment that represents orders from customers. It is not necessary to model customers as agents or objects, but this could also be possible. The perception of receiving a customer order is modeled as CustomerOrder non-action event as shown in Figure 8, “Internal AOR model of the Retailer node.”. It also has a property quantity to specify the amount of ordered beer. When perceiving this event, rule R1 applies and changes the state of the Retailer node by adding the value of the quantity property to the currentSalesOrderQuantity property of the agent. The next rule R2 applies when the agent receives a BeerDelivery perception from the next node in upstream direction. This rule has the same functionality as the same rule for all usual nodes. Finally, rule R3 applies after the Retailer node perceives the non-action event EndOfWeek. In contrast to all other nodes, the Retailer node cannot ship beer to a node in downstream direction. Thus, this rule only results in creating a new Order message and the same state changes as for all other nodes.

Figure 8. Internal AOR model of the Retailer node.

Internal AOR model of the Retailer node.

3.5.2.2. Identifying AOR Entity Types

As will be shown in the following, the Beer Game uses nearly all AORSML entity types. It is also well suited for developing the language and the simulator, since it needs some functions in the language that are not possible to create with AbSimML or are not implemented in the ABSim simulation system. The basic version of the Beer Game in AORSML uses only agents but no objects. While all supply chain nodes are modeled as agents, the beer is not modeled as a physical object. Figure 9, “The SupplyChainNode agent.” shows the definition of a node in the Beer Game. The new agent SupplyChainNode inherits from Agent. It has four self belief properties. First, the inventory property that holds the current stock quantity. In the example, all agents will start with a beer quantity of 10. Then, every agent has a property currentSalesOrderQuantity, specifying the amount of ordered beer in the current round. If an agent wasn't able to satisfy all needs, the remaining quantity will be stored with the property backorderQuantity. Finally, the property costs will be used for computing and storing the current costs of a specific supply chain node. The SupplyChainNode agent has only self belief properties specifying the internal state of the agent. This also means that every node only knows its own state but nothing about the inventory of the next node for instance. All four agents, the Retailer, Wholesaler, Distributor and the Factory can all be modeled as instances of a supply chain node agent. There is also a fifth agent in the AORSML version of the beer game: the RawMaterialsSupplier. This node is not an extension to the game. As mentioned before, the factory node has no real node in upstream direction to order and receive beer from. Since ordering beer is a message and messages must specify the receiving node, the factory needs another node to send orders to[17]. The fifth node will simply receive beer orders from the factory node and then ship the desired amount back to the other node independent from the stock quantity of the node.

Figure 9. The SupplyChainNode agent.

The SupplyChainNode agent.

As mentioned above, to order beer from another supply chain node, an agent has to send a message to that agent. The message must contain the quantity of ordered beer. Besides this, the message must contain the id and type of the sender and the receiver plus the duration. Below, Figure 10, “The beer order message type.” shows the message entity Order for creating beer orders. As can be seen, the id's and types of the sender and receiver and the duration are properties that are already included in the Message entity type[18]. Thus, only the quantity property must be defined for the beer order message.

Figure 10. The beer order message type.

The beer order message type.

Furthermore, the Beer Game needs a set of events for different purposes. Figure 11, “Events for the Beer Game.” gives an overview of all needed events and their dependence to the basic entity types. As can be seen, there are three internal events and also three environment events. Internal events are events that an agent receives from the environment simulator or events that are created internally from the agent simulator. The CustomerOrder and the BeerDelivery event are both perception events that agents will receive from the environment simulator. Both inherit from the entity type PerceptionEvent, thus, there are two basic properties specifying the id and type of the perceiving agent. The CustomerOrder perception event is used to notify to an agent that there is a new beer request from the customer. It has the property quantity specifying the amount of requested beer. The other perception event, BeerDelivery, also has a property quantity. Here, it symbolizes the amount of beer delivered from another agent to the perceiving agent. The last internal event, EndOfWeek, is an internal periodic time event that notifies every supply chain node about the end of one simulated week. This event is necessary, since some supply chain node activities should be done after the end of each week, like shipping ordered beer or calculating the current costs of each node. Besides these three internal events, there are also three environment events. Those events can be action events from agents, caused events that are the result of a previous simulation cycle or exogenous events from outside the simulation environment. For shipping beer from one agent to another, an agent creates a ShipBeer event. This entity type inherits from ActionEvent, thus, it already has two basic properties from the action event entity type. The two properties specify the id and type of the acting agent. The ShipBeer event also has a property that is used to carry information about the quantity of the shipped beer. The CustomerDemand event is an exogenous event to create customer beer orders in periodic intervals. It has no own property. The requested beer amount will be determined with a rule. The last environment event is used to satisfy the Beer Game demand that deliveries will take two simulation cycles. Thus, after the environment simulator received a ShipBeer action event, a ShippingDelay event will be created. This event gets processed in the next simulation step. To store all necessary information, there are two properties, the quantity property for the shipped beer amount and the shipperID property for the id of the node that has shipped the beer.

Figure 11. Events for the Beer Game.

Events for the Beer Game.

3.5.2.3. Initial System State

After identifying all needed entity types, this section now describes the initial state of a Beer Game simulation. As mentioned, there are four players in a Beer Game simulation: the Retailer, Wholesaler, Distributor and the Factory. All four players will be instances of the agent entity type SupplyChainNode. As described above, there is another fifth agent, called RawMaterialsSupplier, that will be used as some kind of helper node to receive orders from the fourth node. Every node needs an initial event instance of the EndOfWeek event. This is a periodic time event, thus, once assigned to an agent, it will occur until it's stop condition gets true. Below, Table 1, “Agent: SupplyChainNode > Retailer shows the initial state of the first node. All other nodes are defined the same, except the fifth node. The helper node needs no inventory, thus, it can remain 0. The instance of the periodic event is the same for all agents. In the example definition, the periodicity is set to 7. The number stands for simulated days, so the event will occur after one whole week as defined for the Beer Game. To bring the simulation to an end, it is necessary to set a stop condition, here: 70 days. Finally, the starting time of the event is set to 7. This marks the very first occurrence of the event. All properties and the internal event define the internal or mental state of the node agent. As mentioned above, every node only knows about it's own state. When trying to investigate dynamics in the Beer Game it might also be interesting to simulate a version, where nodes know about the state of all others and adjust there decisions. Since, the result of the Beer Game are not of interest here, the simple version will be enough.

Table 1. Agent: SupplyChainNode > Retailer

inventory10
currentSalesOrderQuantity0
backorderQuantity0
costs0
Event InstanceEndOfWeek
  • periodicity = 7

  • stopCondition = occurrenceTime > 70

  • startingTime = 7


Next, after defining all initial agent states, it is necessary to create an instance of the exogenous event defined for the Beer Game: the CustomerDemand. This event is needed to create customer beer demand in periodic intervals for the first supply chain node. Since it should occur once a week, the periodicity is set to 7. This periodic event is also limited to 70 simulation days and starts after the first 7 days.

Table 2. Exogenous Event: CustomerDemand > AutomaticBeerDemand

periodicity7
stopConditionoccurrenceTime > 70
startingTime7

The initial state definition described above is completed with the definition of all agent start states and all periodic events. All other events and messages used in the Beer Game will be initialized within the game. The next sections now introduce the processes within the Beer Game as Agent-Object-Relationship Simulation.

3.5.2.4. Exogenous Event CustomerDemand

The exogenous event CustomerDemand is used to create external beer orders. This event is necessary since the first node Retailer has no node in downstream direction of the chain to receive orders from. The event has no own properties, the amount of requested beer will be generated with the associated rule shown in Table 3, “Environment Rule: RuleCustomerDemand. There is no condition, no resulting environment event and no state effect when processing the rule of the event. There is one resulting perception: CustomerOrder. Since this event should be perceived by the first node, the perceiverID is set to 1. The occurrence time of the resulting perception seams misleading in the first moment, since the time of the perception is a bit lower than the occurrence time of the triggering event. The reason is that the simulation system processes the environment simulator step before all agent simulators in the same cycle. If a new created perception should be perceived in the same cycle, the occurrence time must be equal to the current environment simulator time. Since all Beer Game agents should perceive orders before reacting to the EndOfWeek event, it is necessary to use a trick to ensure that the incoming order is processed first. For this reason, the occurrence time of the resulting perception will be lower than the triggering events occurrence time. Finally, the rule computes a random value for the quantity of ordered beer. In the example it will be a value between 1 and 10.

Table 3. Environment Rule: RuleCustomerDemand

Triggering EventCustomerDemand
Condition-
Resulting Environment Events-
Resulting PerceptionsCustomerOrder
  • occurrenceTime = CustomerDemand.occurrenceTime - 1

  • perceptorID = 1

  • quantity = Random.uniformInt(1, 10)

State Effects-

3.5.2.5. Perception Event CustomerOrder

The CustomerEvent is the perception of an incoming customer beer request. Since, the id of the perceiving agent is always 1, it is not necessary to define a condition to apply the rule. There are no resulting events, actions or messages. But, the incoming order changes the state of the perceiving node. The ordered quantity will be added to the node's currentSalesQuantity property.

Table 4. Agent Rule: RuleIncomingCustomerOrder

Triggering EventCustomerOrder
Condition-
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • currentSalesOrderQuantity = currentSalesOrderQuantity + Order.quantity


3.5.2.6. Action Event: ShipBeer

When an agent creates an action event, this event will be processed by the environment simulator. The shipment of beer is modeled as an action and gets processed by the environment simulator. By definition, the shipment of beer takes two weeks in the simulation. The resulting beer perception must be delayed for this reason. Thus, a perception signal event will be created as result of the environment rule for the ShipBeer action event. The resulting perception signal event ShippingDelay is an environment event and will be processed in a future simulation cycle. For creating a one week delay, the time will be incremented by 7 days. The resulting event has two own properties defining the amount of beer and the id of the shipper node. Both values are taken from the triggering event.

Table 5. Environment Rule: RuleCreateShippingDelay

Triggering EventShipBeer
Condition-
Resulting Environment EventsShippingDelay
  • occurrenceTime = ShipBeer.occurrenceTime + 7

  • quantity = ShipBeer.quantity

  • shipperID = ShipBeer.actorID

Resulting Perceptions-
State Effects-

3.5.2.7. Environment Event: ShippingDelay

The environment event ShippingDelay is needed for the delay of a beer delivery. The actual delivery event will be created when the delay event occurs. Below, Table 6, “Environment Rule: RuleShipBeer shows the corresponding rule for the triggering delay event. The resulting perception event has a property for the quantity of the shipped beer. The id of the perceiving agent is the id of the shipping agent incremented by one, since all supply chain nodes are numbered from 1 for the Retailer node to 4 for the Factory node.

Table 6. Environment Rule: RuleShipBeer

Triggering EventShippingDelay
Condition-
Resulting Environment Events-
Resulting PerceptionsBeerDelivery
  • occurrenceTime = ShippingDelay.occurrenceTime - 1

  • perceptorID = ShippingDelay.shipperID-1

  • quantity = ShippingDelay.quantity

State Effects-

3.5.2.8. Perception Event: BeerDelivery

The perception BeerDelivery informs an agent about an incoming beer delivery. The agent rule that processes this event, simply adds the received amount of beer to the inventory of the agent. There are no resulting events or messages.

Table 7. Agent Rule: RuleIncomingBeerDelivery

Triggering EventBeerDelivery
Condition-
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • inventory = inventory + BeerDelivery.quantity


3.5.2.9. Message: Order

An incoming Order message is processed in the same way as the CustomerOrder perception event. The rule only changes the state of the receiving agent by adding the quantity of the incoming order to the currentSalesOrderQuantity property of the agent. There are no resulting events.

Table 8. Agent Rule: RuleIncomingOrder

Triggering EventOrder
Condition-
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • currentSalesOrderQuantity = currentSalesOrderQuantity + Order.quantity


3.5.2.10. Periodic Event: EndOfWeek

The periodic time event EndOfWeek occurs every week for every agent. It is used for computing the amount of beer to ship and to order and to compute the costs of a supply chain node. There are rules for all different purposes and for different conditions. The first two rules, shown in Table 9, “Agent Rule: RuleShippingAllOrders and Table 10, “Agent Rule: RuleShippingAvailableAmount are used for the shipping of beer of the nodes 2, 3 and 4. The first node and the helper node have own rules for shipping beer. The first rule RuleShippingAllOrders applies only when the node's inventory is at least as high as the sum of all current orders and all backorders from previous rounds. In this case, the resulting shipping action is assigned the quantity of all orders of this node. The shipping of beer changes the state of the agent. It's inventory will be decremented by the shipped quantity. The currentSalesOrderQuantity and the backorderQuantity properties are set to 0.

Table 9. Agent Rule: RuleShippingAllOrders

Triggering EventEndOfWeek
Conditionid not 1 and id not 5 and inventory >= (currentSalesOrderQuantity + backorderQuantity) and (currentSalesOrderQuantity + backorderQuantity) > 0
Resulting Internal Events-
Resulting ActionsShipBeer
  • quantity = currentSalesOrderQuantity + backorderQuantity

Resulting Messages-
State Effects
  • inventory = inventory - (currentSalesOrderQuantity + backorderQuantity)

  • backorderQuantity = 0

  • currentSalesOrderQuantity = 0


The second rule is used in the case the agent has not enough beer in stock to satisfy all orders but the inventory is not 0. The agent will then ship the complete inventory. The inventory will then logically set to 0. The new value for the backorderQuantity property is then the sum of all current and old orders decremented by the shipped amount of the complete inventory. Since the current rest orders were added to the backorders, the currentSalesOrderQuantity can be set 0.

Table 10. Agent Rule: RuleShippingAvailableAmount

Triggering EventEndOfWeek
Conditionid not 1 and id not 5 and inventory < (currentSalesOrderQuantity + backorderQuantity) and inventory > 0
Resulting Internal Events-
Resulting ActionsShipBeer
  • quantity = inventory

Resulting Messages-
State Effects
  • backorderQuantity = (backorderQuantity + currentSalesOrderQuantity) - inventory

  • inventory = 0

  • currentSalesOrderQuantity = 0


The next two rules are used only for the first node. The Retailer node cannot ship beer to another node, since there is no node in downstream direction. Thus, only the internal state of the node will be changed. The first rule will be applied when the node has enough beer in stock for all current orders and backorders. The inventory will be decremented by the sum of all orders. The orderedSalesOrderQuantity and the backorderQuantity properties will be set to 0. The rule shown in Table 12, “Agent Rule: RuleShippingAvailableAmountToCustomer applies for the second possible case that the Retailer node has not enough beer in stock to satisfy all orders. The backorderQuantity property gets incremented by the currentSalesOrderQuantity and then decremented by the value of the inventory property. After this, the inventory and currentSalesOrderQuantity will be set to 0.

Table 11. Agent Rule: RuleShippingAllCustomerOrders

Triggering EventEndOfWeek
Conditionid = 1 and inventory >= currentSalesOrderQuantity + backorderQuantity
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • inventory = inventory - (currentSalesOrderQuantity + backorderQuantity)

  • backorderQuantity = 0

  • currentSalesOrderQuantity = 0


Table 12. Agent Rule: RuleShippingAvailableAmountToCustomer

Triggering EventEndOfWeek
Conditionid = 1 and inventory < currentSalesOrderQuantity + backorderQuantity
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • backorderQuantity = (backorderQuantity + currentSalesOrderQuantity) - inventory

  • inventory = 0

  • currentSalesOrderQuantity = 0


Finally, there is also a shipping rule for the helper node. This node will always send all received orders to the Factory node. Thus, there is a resulting action with the amount of the currentSalesOrderQuantity property as value for the quantity property of the ShipBeer event. Thus, the Factory node will directly receive all orders.

Table 13. Agent Rule: RuleShippingRawMaterials

Triggering EventEndOfWeek
Conditionid = 5 and currentSalesOrderQuantity > 0
Resulting Internal Events-
Resulting ActionsShipBeer
  • quantity = currentSalesOrderQuantity

Resulting Messages-
State Effects-

After processing all shipping rules of the EndOfWeek event, there are two more rules to process. Both rules will only be applied to nodes 1 to 4, since the helper node cannot order beer and don't needs to calculate any costs. The first rule shown in Table 14, “Agent Rule: RuleOrderingStock is needed for creating new beer orders. As described in [Beer04] there are different strategies for choosing the amount of beer to order that lead to very different simulation results. But, for the example shown here, the final results of the Beer Game simulation are not important. Thus, every agent will order a random value of beer between 1 and 10. The receiverID of the resulting message is the id of the sender node incremented by 1. The duration is 7 days and the reliability is simply 1. This means, the message will always arrive. A value lower than 1 minimizes the probability that the message arrives at the sender.

Table 14. Agent Rule: RuleOrderingStock

Triggering EventEndOfWeek
Conditionid not 5
Resulting Internal Events-
Resulting Actions-
Resulting MessagesOrder
  • receiverID = id+1

  • duration = 7

  • reliability = 1

  • quantity = Random.uniformInt(1, 10)

State Effects-

The last rule to process, rule RuleCalculatingCosts, is used to calculate the current costs of every supply chain node and add the result to the overall costs of the node. The current costs are composed of costs for remaining inventory and all backorders of the current round. Inventory costs can be seen as stock holding costs and are charged one money unit per inventory unit. Backorder costs are shortage costs and will be charged with two money units per backorder unit. The sum of both costs will finally be added to the costs property of the node.

Table 15. Agent Rule: RuleCalculatingCosts

Triggering EventEndOfWeek
Conditionid not 5
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • costs = costs + (1 * inventory) + (2 * backorderQuantity)


3.6. Introducing Advanced Language Extensions

While working on the Beer Game as AOR simulation with AORSML, there had been a lot of ideas to enhance the game. But, these could not be included due to limitations of the simulation language. In these cases, the clear structure of a declarative language proved to be a large disadvantage. Towards programming languages where the language elements usually allow to realize most ideas, declarative languages mostly only allow a fixed set of possibilities [GamesAI04]. Thus, new language features require language extensions. Extending the XML language requires always extensions in the Java code generation. These extensions will not be explained here. The following sections now introduce the extensions to the basic AORSML language. Section 3.6.1, “Creating Sets” starts with the possibility of creating sets of agent and object instances. The next section introduces the possibility to create new agent and object instances later in a simulation. To continue, Section 3.6.3, “Destroying Agents and Objects in a Running Simulation” shows how agents and objects can be destroyed in a running simulation. Finally, Section 3.6.4, “Changing the State of a large Set of Entities” introduces a construct to change the state of a group of agents or objects when the modification should be the same for all members of the group.

3.6.1. Creating Sets

In the Beer Game version described above, all agents had the same initial state, but it was necessary to define the state for every single agent. This is sufficient for a small amount of agent or object instances. But when wanting to create a lot of unique agents or objects, simulation files would become pretty large. Thus, the language got extended with an element that allows to create sets of agent instances and an element to create object instance sets. The first listing shows the definition of an agent instance set. As for a normal agent instance, the set also has the attributes instanceOf and name. The first defines the type of the agent, the second simply defines an identifier. There are two more attributes that are needed to specify parameters for the set. The first attribute startID defines the id of the first agent to create. The amount attribute specifies how many agents should be created. The id of every agent is computed by the startID and the number of the agent in the set. For example if the startID is 10 and amount is 5, the id of the last agent will be 14. The rest of the instance declaration is equal to the usual AgentInstance element. See Section 3.3.4.1, “AgentInstance” for detailed information.

<AgentInstanceSet instanceOf="..." startID="..." amount="..."  name="...">
  <Slot property="..." value="..."/>
  <SelfBeliefSlot selfBeliefProperty="..." value="..."/>
  <EventInstance stereotype="..." instanceOf="EndOfWeek" name="...">
    <Slot property="startingTime" value="..."/>
    <Slot property="agentType" value="..."/>
  </EventInstance>
</AgentInstanceSet>

The next listing shows the definition of the new element ObjectInstanceSet. The syntax for defining the first id and the amount of objects is equal to the definition of the AgentInstanceSet element. Like for a single object instance declaration, the set can contain Slot elements to define initial values for object properties.

<ObjectInstanceSet instanceOf="..." startID="..." amount="..."  name="...">
  <Slot property="..." value="..."/>
</ObjectInstanceSet>

3.6.2. Creating Agents and Objects in a Running Simulation

The Beer Game version described above defines the beer very abstract. There are no beer objects that are shipped between the agents, only numbers are used to display beer quantities. To use real AOR objects for the beer, it is necessary to create new objects in a running simulation. This requires on the one hand a new element in the language and on the other hand changes in the simulator functionalities. In case of a new object, the simulation system must be able to create a new instance and insert it in the list of objects. In case of a new agent, the simulation system must not only create a new agent instance but also create a new internal agent plus a new agent simulator for this internal agent. The first step in adding this new feature to AOR simulations is to decide where to place the extensions in the simulation language. Since the language should not be changed in the basic structure to keep the main simulation principles, the idea was to use and only extend the existing AORSML elements. As described earlier, AOR simulations use rules to define the behavior between agents and objects as well as to define all other processes in the simulation. Rules are used to create resulting events and to change the state of agents and objects, hence the state of the whole simulation. Thus, the decision is to include the creation of new physical objects inside rules. But, only environment rules may be used for this. Agent rules should only affect the internal or mental state of an agent without a direct influence of other physical objects[19]. Thus, the new element for creating agents and objects is included in the EnvironmentRule element. The listing below shows the new element createPhysicalObject under the EnvironmentRule element. The already introduced elements for creating instances of agents and objects as described in Section 3.3.4.1, “AgentInstance” and Section 3.3.4.2, “ObjectInstance” will be reused here. It is also possible to create sets of new agents and objects. This can be done with the new elements introduced in Section 3.6.1, “Creating Sets”.

<EnvironmentRule name="...">
  <triggeringEventExpr>
    ...
  </triggeringEventExpr>
  ...
  <createPhysicalObject>
    <AgentInstance instanceOf="..." name="..." id="...">
      <Slot property="..." value="..."/>
      <SelfBeliefSlot selfBeliefProperty="..." value="..."/>
      <EventInstance stereotype="..." instanceOf="..." name="...">
        <Slot property="..." value="..."/>
      </EventInstance>
    </AgentInstance>
    <AgentInstanceSet...>
      ...
    </AgentInstanceSet>
    <ObjectInstance instanceOf="..." name="..." id="...">
      <Slot property="..." value="..."/>
    </ObjectInstance>
    <ObjectInstanceSet instanceOf="..." startID="..." amount="..." name="...">
      <Slot property="..." value="..."/>
    </ObjectInstanceSet>
  </createPhysicalObject>
</EnvironmentRule>

3.6.3. Destroying Agents and Objects in a Running Simulation

When creating physical objects in a running simulation, it must also be possible to destroy physical objects. For this purpose, a new element destroyPhysicalObject was created and, like the createPhysicalObject element, defined under the EnvironmentRule element. As the listing below shows, it has four sub elements. The first two elements are used to destroy agents and sets of agents and the other two for the same purposes in reference to objects. Destroying an agent or object requires two attributes specifying the type and id of the physical object to destroy. Destroying a set always means a set of agents or objects with consecutive id's. The set definition requires the type attribute plus the attribute startID specifying the lowest id in the set and, finally, the attribute amount.

<EnvironmentRule name="...">
  <triggeringEventExpr>
    ...
  </triggeringEventExpr>
  ...
  <destroyPhysicalObject>
    <Agent type="..." id="..."/>
    <AgentSet type="..." startID="..." amount="..."/>
    <Object type="..." id="..."/>
    <ObjectSet type="..." startID="..." amount="..."/>
  </destroyPhysicalObject>
</EnvironmentRule>

3.6.4. Changing the State of a large Set of Entities

In simulations with a large amount of agents or objects, sometimes the state of several physical objects changes at the same moment. In case of the Beer Game, when using AOR objects as beer, sending 10 beer objects would change the state of all these 10 beer objects at the same moment. Instead of adding 10 assign elements to the stateEffects element of the specific rule, one single element that can handle all these assigns would be favorably. The next listing shows a new language element that can handle this. The element GroupAssign must be defined like all other assigns under stateEffects. Since only the environment simulator has access to the external state of all agents and objects, only environment rules can contain GroupAssign elements. The element itself can contain the elements AgentSet and ObjectSet. These two elements have the required attributes type, startID and amount. The first defines the type of the agent or object entity. The startID attribute specifies the first id in the set and amount the number of agents or objects. Both set elements can contain an arbitrary amount of assign elements to specify the property to change and an expression of the new value.

<EnvironmentRule name="...">
  <triggeringEventExpr>
    ...
  </triggeringEventExpr>
  ...
  <stateEffects language="Java">
    <GroupAssign>
      <AgentSet type="..." startID="..." amount="...">
        <assign property="..." valueExpression="..."/>
      </AgentSet>
      <ObjectSet type="..." startID="..." amount="...">
        <assign property="..." valueExpression="..."/>
      </ObjectSet>
    </GroupAssign>
  </stateEffects>
</EnvironmentRule>

3.7. Extending the Beer Game Simulation with new Language Features

With the help of the new features in the AOR simulation markup language, it is possible to create even more complex simulations. To show an example usage, this sections introduces an advanced version of the Beer Game simulation. The advanced version extends the game by the possibility to insert new nodes into the supply chain and to remove nodes from the chain. This requires a lot of changes and extensions to the simulation definition. In the basic version, every node orders beer from the node in upstream direction of the chain and ships beer to the node in downstream direction. Since nodes are numbered from 1 for the lowest node in the chain to 4 for the highest node, every node simply sends orders to the node id+1 where id is it's own id and ships beer to the node id-1. But, inserting and removing nodes would not be possible in this way. To enable this, the chain must be build up like a linked list, where every node has a reference to the node it will order beer from and to the node it will ship beer to. Thus, every node must hold an reference to the next node in the chain and to the previous node. Figure 12, “Modifiable supply chain.” shows the basic structure. Every node has a reference order from that points to the node it will send beer orders to and ship to that points to the node to which beer will be shipped.

Figure 12. Modifiable supply chain. Every node holds a reference to the next and previous node.

Modifiable supply chain. Every node holds a reference to the next and previous node.

To insert a new node in this supply chain, the pointers[20] of the two nodes where to insert the new one must be changed. Figure 13, “Inserting a new node into the chain.” shows the insertion process. In step (1), the order from pointer must be set to the node that should be next in the chain and the ship to pointer of the node must be set to the node that should be previous. After this, step (2) changes the ship to pointer of the node one place up in upstream direction to the new node and also the order from pointer of the lower node to the new one. After this, it is possible to use the supply chain with the new node. Removing a node is then exactly the opposite way.

Figure 13. Inserting a new node into the chain.

Inserting a new node into the chain.

The following sub sections now introduce all changes, including new events and rules, that had to be modeled to create the advanced version of the Beer Game simulation. Appendix C, An Advanced Beer Game Version shows these new elements as AORSML simulation script.

3.7.1. New and Adapted AOR Entity Types

To model the extended Beer Game simulation, it is necessary to adapt or completely new create different entity types. But, except the agent entity type of the supply chain node, all other existing entities could be used without any change. The agent entity had to be extended with two new properties as Figure 14, “Extended supply chain node.” shows. The orderFromNode property references the node to which this node will send beer orders. The default value for this property is like in the basic game version id+1. The shipToNode property is used for referencing the node that should receive shipped beer. The default value also is simply the id of the node one place in downstream direction. All other properties are used again here.

Figure 14. Extended supply chain node.

Extended supply chain node.

There are several new events that are necessary to add or remove nodes and for informing existing nodes about this. The appearing and disappearing of a node is modeled as an exogenous event, since it should not depend on another event within the simulation environment. The exogenous event AppearingNode is used when a new node appears, the event DisappearingNode when a node will disappear. After a new agent appeared or an existing disappeared, it is necessary to inform the two nodes that are directly affected by this. For this purpose, there are two new perception events. The first, ChangingUpStreamNode, informs a node that there is a new node in upstream direction to send beer orders to. It has a property newOrderFromNode that refers to the id of the node from which beer should be ordered in the future. The second perception event, ChangingDownStreamNode, informs a node that there is another node that should receive beer shipments. The property newShipToNode must refer to the id of this agent.

Figure 15. New perception and exogenous events.

New perception and exogenous events.

3.7.2. Initial System State

There are only small changes in the initial state definition of the whole simulation. All instances described for the basic Beer Game are also defined here. There are only two new instance definitions for the two new exogenous events. In the example simulation here, one new node will appear and the same node will disappear later. Thus, both events are only used once. The AppearingNode event will occur after 21 days and then be stopped. The DisappearingNode will occur two weeks later.

Table 16. Exogenous Event: AppearingNode > appearingNode

periodicity7
stopConditionoccurrenceTime > 21
startingTime21

Table 17. Exogenous Event: DisappearingNode > disappearingNode

periodicity7
stopConditionoccurrenceTime > 35
startingTime35

3.7.3. Exogenous Event AppearingNode

Since all other events are processed in the same way as in the basic Beer Game version, only the new events are shown in the following. The first event is the exogenous event AppearingNode. Below, Table 18, “Environment Rule: RuleAppearingNode shows the corresponding rule that is triggered by this exogenous event. There is no condition and there are no resulting environment events. But, there are two resulting perceptions. The first, ChangingUpStreamNode, is used to inform the node that will be the previous node of the new node that the new node will now receive orders. In the example, the new node should be inserted between nodes 2 and 3. Thus, node 2 must now send orders to the new node. Node 3 on the other side, should now ship beer orders to the new inserted node. For this purpose, perception event ChangingDownStreamNode is created and send to node 3. As can be seen, both events have a different occurrence time. The ChangingUpStreamNode perception event has the current time decremented by one simulation day. The reason for this is, that this event should be processed first when received by an agent before processing the EndOfWeek event. Since, the agent simulation step is done in the same simulation cycle, but after the environment simulator, the time must be decremented as described in Section 3.5.2.4, “Exogenous Event CustomerDemand. When processed before the EndOfWeek event, it is possible, that the new orders created in the current round will already be send to the new node. With the changing node in downstream direction it is a bit more complicated. When this perception gets processed first, the node would ship all current orders already to the new node. But, all current orders have been sent to the node by the old node in downstream direction. Thus, all current orders should usually be shipped to the old node and the change in the chain in downstream direction should then be processed afterwards. In fact, this is a serious problem and might only be solved when every agent saves not only received beer order amounts but every single order with the sender of the message. In the solution described here, it will be assumed that, after inserting a new node, all current orders and all backorders should already be shipped to the new inserted node.

Table 18. Environment Rule: RuleAppearingNode

Triggering EventAppearingNode
Condition-
Resulting Environment Events-
Resulting PerceptionsChangingUpStreamNode
  • occurrenceTime = AppearingNode.occurrenceTime - 1

  • perceptorID = 2

  • newOrderFromNode = 6

ChangingDownStreamNode
  • occurrenceTime = AppearingNode.occurrenceTime - 1

  • perceptorID = 3

  • newShipToNode = 6

Create Physical ObjectAgentInstance
  • instanceOf = SupplyChainNode

  • id = 6

  • name = newNode

Destroy Physical Object-
State Effects-

As described before, environment rules can now contain elements for creating or destroying physical objects. The rule above creates a new instance of a supply chain node agent to insert it into the supply chain. The agent has the id 6 and is simply named newNode. Below, Table 19, “Agent: SupplyChainNode > newNode shows details about the new agent. As mentioned before, it will be inserted into the chain between agents 2 and 3. Thus, property orderFromNode is set to 3 and property shipToNode is set to 2. As every supply chain node agent, also this agent needs an instance of the periodic time event EndOfWeek.

Table 19. Agent: SupplyChainNode > newNode

orderFromNode3
shipToNode2
Event InstanceEndOfWeek
  • periodicity = 7

  • stopCondition = occurrenceTime > 70

  • startingTime = 21


3.7.4. Exogenous Event DisappearingNode

The exogenous event DisappearingNode is used to remove the newly inserted agent from the supply chain. Thus, after removing this node, the initial chain must be restored. To do this, the corresponding rule will create two perception events as resulting events. The first, ChangingUpStreamNode, informs node 2 that it must now order beer from node 3. The other perception, ChangingDownStreamNode, informs node 3 that is must ship beer again to node 2. Finally, this rule invokes the destruction process to remove the agent from the simulation system.

Table 20. Environment Rule: RuleDisappearingNode

Triggering EventDisappearingNode
Condition-
Resulting Environment Events-
Resulting PerceptionsChangingUpStreamNode
  • occurrenceTime = DisappearingNode.occurrenceTime - 1

  • perceptorID = 2

  • newOrderFromNode = 3

ChangingDownStreamNode
  • occurrenceTime = DisappearingNode.occurrenceTime - 1

  • perceptorID = 3

  • newShipToNode = 2

Create Physical Object-
Destroy Physical ObjectAgent
  • type = SupplyChainNode

  • id = 6

State Effects-

3.7.5. Perception Event ChangingDownStreamNode

The perception event ChangingDownStreamNode informs an agent about a new node in downstream direction of the supply chain. The corresponding rule simply changes the internal state of the affected agent by changing its shipToNode property to the value given with the newShipToNode property of the triggering event.

Table 21. Agent Rule: RuleChangingDownStreamNode

Triggering EventChangingDownStreamNode
Condition-
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • shipToNode= ChangingDownStreamNode.newShipToNode


3.7.6. Perception Event ChangingUpStreamNode

The perception event ChangingUpStreamNode informs an agent about a new node in upstream direction of the supply chain. The corresponding rule only changes the internal state of the affected agent. The orderFromNode property of the agent will be set to the value given with the newOrderFromNode property of the triggering event.

Table 22. Agent Rule: RuleChangingUpStreamNode

Triggering EventChangingUpStreamNode
Condition-
Resulting Internal Events-
Resulting Actions-
Resulting Messages-
State Effects
  • orderFromNode= ChangingUpStreamNode.newOrderFromNode


4. AOR-JSim - A Java Code Generator and Simulator for AOR Simulations

AOR-JSim is a powerful software for generating and executing Agent-Object-Relationship simulations. The simulator generates Java classes from a given AORSML file. These classes can then be compiled and executed directly with it. AOR-JSim is based on the AbSim [Raf05] simulation system. Since AbSim wasn't fully developed, it had to be revised completely. This includes a new and much more comprehensive user interface, optimized and enhanced core functionalities. Furthermore, the functional range of AOR-JSim got extended with some new functionalities.

To start, Section 4.1, “Analyzing the AbSim Java Simulation System” analyzes the given simulation system AbSim. The following section then gives a short introduction to the new simulator. After this, the next sections show the functionalities of AOR-JSim in detail including a complete description of the improved parts and extensions. Section 4.4, “Java Code Generation” explains the automatic generation of Java source code. After this, Section 4.5, “Running Simulations” describes the process of compiling and executing generated simulations with AOR-JSim. The next section introduces a way to manage projects and finally, Section 4.7, “Creating Structured Simulation Output” describes the creation of a structured output file.

4.1. Analyzing the AbSim Java Simulation System

The Java simulation system that this work introduces is based on the AbSim simulation system. The AbSim system is an agent based simulation system and included in the abobsim simulation system. This simulation system, also written in Java, combines object based simulation and agent based simulation in one software. The abobsim simulation system never transcended a test state as mentioned by the developer W. U. Raffel within his dissertation: "Die Implementierung des in Java geschriebenen Simulators, die den Charakter eines proof of concept und nicht eines fertigen Softwareproduktes hat,..." [Raf05] (135) [Author's translation: the implementation of the Java simulator, that has the character of a proof of concept and not of a finished software product...] The biggest part of this work is to extend the AbSim simulation system to enable Agent-Object-Relationship Simulation and to improve the given version in case of faulty or unfinished parts. This task is divided into two parts. First it is necessary to analyze the software to check what can still be used and what needs to be changed and extended to support AOR Simulations. Since AbSim is a part of the larger simulation software abobsim, it is necessary to extend this analyzation to the whole simulation system. This is done in Section 4.1.1, “Analyzing the Structure of abobsim”. The second task is then to improve the software and to add more functions to make it more useful to developers. Section 4.1.2, “Necessary Improvements and Extensions” deals with this task. Below, Figure 16, “A screenshot of abobsim.” shows a screenshot from the user interface of the abobsim system.

Figure 16. A screenshot of abobsim. This system combines agent and object based simulation. This means, both simulations are supported by the software.

A screenshot of abobsim. This system combines agent and object based simulation. This means, both simulations are supported by the software.

4.1.1. Analyzing the Structure of abobsim

The abobsim simulation system is used to generate object and agent based simulation files from XMI input files, to create Java source code from these simulation files, to compile the code and finally to run the generated simulations. The whole software package consists of three packages. There is one package for every simulation system, containing base classes of simulation entities and classes for simulation management. Package absimulation is used for agent based simulations and package obsimulation for object based simulations. The third package abobsim is the main package for starting the software, creating the user interface, generation of simulation files and Java code, compilation of code and for running simulations. Figure 17, “Package diagram of the abobsim generator software.” shows a package diagram of the main package abobsim and its sub packages. To use the software for Agent-Object-Relationship Simulation, some parts must be changed and some parts can be removed completely. Since AOR Simulations extend agent based simulations, package absim and its sub packages can be used but must be extended to support AOR simulations. But, the package for object based simulation generation obsim can be removed completely. As can be seen in the package diagram, there are two exception packages classcreation.exceptions and classcreation.absim.exceptions[21]. The exceptions within classcreation.absim.exceptions are exceptions when creating agent based simulation code. Since the new software only needs to support one simulation system, the two exception packages can be merged to only one package. The package helpers is another package that is removed completely. This package contains classes for converting the input XMI files to ABSimML or OBSimML. The new software version uses XML based AOR simulation files directly, there will be no XMI conversion any longer. The parser package will also be deleted. It is used for parsing OCL statements as contained in ABSimML. The new XML language AORSML doesn't uses OCL statements, thus, the package parser also gets removed. Finally, package treetests is removed since it only contains some test classes.

Figure 17. Package diagram of the abobsim generator software.

Package diagram of the abobsim generator software.

As mentioned, the AORSML language is based on ABSimML. Also AOR simulations are based on agent based simulations. Therefore, it is not necessary to completely re-implement Java code generation for AOR simulations. The classes included in the package absim and its sub packages only must to be adapted to use them for creating AOR simulation Java code. The mechanism remains the same: first, the given XML based simulation file needs to be parsed, then the relevant information must be found and categorized and finally, Java source code must be created with this information. This mechanism gets adapted to support AOR simulations. Besides, the code generation classes have been checked for improvements and optimizations. The final Java code generation process for AOR simulations can be found in Section 4.4, “Java Code Generation”.

4.1.2. Necessary Improvements and Extensions

To enhance the simulator software it is necessary to revise the user interface and to think about useful extensions. The given version of abobsim is not fully developed. The user interface only contains the minimal necessary functionalities to let the user create and run simulations. In addition, the user interface implementation is not very good. The complete creation of the graphical user interface is done with one single method of class UserInterface of package abobsim.gui. This means, all graphical elements get created and configured within one large block of instructions. This lowers the overview on the source code and leads to harder code maintenance and extension. Thus, the user interface implementation is completely re-implemented and unitized. The new user interface main class has now several methods for GUI creation. Every method is responsible for a certain part of the surface. Plus, some user interface components are put into extra classes. This makes it easier to substitute components or to use them again in other projects. Section 4.3, “Creating an Enhanced User Interface” presents the new user interface structure. Beyond this, several new functions have been included into the user interface to make it more useful to developers. The following extensions have been made:

  • validation of simulation input files with XML Schema

  • enabling editing of simulation files and generated Java code

  • direct saving of simulation output during simulation execution

  • support of projects

    • collecting relevant project data

    • saving project files

    • restoring project data

  • creation of a simulation control center

    • support of step-wise simulation execution

    • enabling pausing and stopping simulation execution

The first three points are described in Section 4.3, “Creating an Enhanced User Interface”. The introduction of project file support is made in Section 4.6, “Creating Project Files” and the simulation control center is explained in Section 4.8, “Implementing a Simulation Control Center”.

4.2. Introduction to AOR-JSim

AOR-JSim is a Java based software tool that generates Java classes from AORSML simulation files and executes them within the environment of the simulator. Beyond this, the simulator has a lot more useful functions. For instance, AOR-JSim supports project files. That means, one can save an arbitrary program state and open it at some point in time later. This makes sense for simulations that have to be repeated often. For this purpose it is also possible to adjust the simulation parameters that determine the amount of cycles a simulation should run directly via the user interface. Here it is not necessary to re-compile the whole simulation. This facilitates long series of measurements. Simulation output that a logger sends to the user interface can also be directed to a file. This makes sense for long running simulations with a lot of data to avoid memory problems. It is also possible to create charts about the developing of simulation values directly with AOR-JSim. This special feature will be explained later in Section 5, “Creating a Statistic Center for Live Evaluationof Simulations in AOR-JSim”.

Figure 18. Screenshot of AOR-JSim.

Screenshot of AOR-JSim.

4.2.1. Simulator Workflow

For generating Java classes, AOR-JSim parses the AORSML file to retrieve all information on the simulation entities. This information is used to create classes that extend basic AOR classes as found in the meta model of the language. This will be explained in detail in Section 4.4, “Java Code Generation”. These new created Java classes get compiled directly with the simulator. No further programming work is necessary for the user. After compilation, the user can run the simulation inside AOR-JSim. While running a simulation, it is possible to pause and continue or even to run a simulation step by step with steps size being adjustable. Furthermore the user can use different simulation loggers to follow the simulation progress. It is also possible to implement an own logger to use it with AOR-JSim. This opens up the possibility to have an appropriate logger for every different simulation. For instance, one can imagine a logger that fills a database at simulation runtime with the data from the simulation. Or another logger that sends created data directly to another program for further processing. Figure 19, “Simulator Workflow” shows the basic workflow of the simulator.

Figure 19. From left to right: AORSML file; generated Java code; compiled Java byte code; simulation output in different formats.

From left to right: AORSML file; generated Java code; compiled Java byte code; simulation output in different formats.

4.2.2. Simulation System Overview

The AOR Java simulation system consists of three main packages. The first package - aorgeneration - contains all classes needed for the user interface and the code generation. Figure 20, “Package diagram for aorgeneration. gives an overview over this package and its sub-packages. Package aorgeneration.gui includes the main class of the simulator that creates the user interface and manages all functions. The second sub-package aorgeneration.aorsml2java contains the classes that parse the AORSML files and create the Java files. Package aorgeneration.aorsml2java.wrappers includes classes that search for specific information within AORSML elements. The classes within aorgeneration.aorsml2java.codecreation use this information to generate Java program code. Finally, package aorgeneration.aorsml2java.exceptions contains some exceptions that may be thrown in code generation.

Figure 20. Package diagram for aorgeneration.

Package diagram for aorgeneration.

The next main package - aorsimulation - includes abstract classes for all AOR entities plus classes for the execution of the simulation. Figure 21, “Package diagram for aorsimulation.” shows a package diagram of aorsimulation. While aorsimulation.agentsimulator includes classes that are needed for simulating agents, sub-package aorsimulation.environmentsimulator includes the classes for running the environment simulator. The sub-package aorsimulation.baseclasses contains most of the abstract classes for the AOR simulation entities. Finally, aorsimulation.util is a small package with some helper classes. The most important class Random provides some methods for generating random numbers.

Figure 21. Package diagram for aorsimulation.

Package diagram for aorsimulation.

The third main package of the simulation system - aorsimstats - contains classes for simulation output logging and the creation of live statistics. See Figure 22, “Package diagram for aorsimstats.” for an overview of this package. The logger architecture will be explained in detail in Section 4.7, “Creating Structured Simulation Output”. Package aorsimstats.event is used to create live statistics with direct chart generation at runtime. More of this feature later in Section 5, “Creating a Statistic Center for Live Evaluationof Simulations in AOR-JSim”.

Figure 22. Package diagram for aorsimstats.

Package diagram for aorsimstats.

4.3. Creating an Enhanced User Interface

An important task is to enhance the given user interface from the abobsim simulation system. Before implementing new functions, it is necessary to revise the user interface. Section 4.1.2, “Necessary Improvements and Extensions” already described problems with the given graphical user interface. Most user interface components are created and configured within one method in class UserInterface. This makes source code maintenance very difficult. Also, adding new components is more complicated. Therefore, the structure of the user interface is completely changed. Figure 23, “Class diagram of main components of the new graphical user interface.” shows the structure of the graphical user interface main classes from AOR-JSim. The user interface now consists of three main classes. Class GUI is the main class for starting the whole software. This class is also responsible for creating the user interface and for ensuring the communication between all components. In opposite to class UserInterface from abobsim, class GUI has a set of methods for initializing different parts of the user interface. The most important method is init. This method delegates different initialization tasks to several other methods. For instance, method initTabs initializes the content areas of all tabs and method initSplitPanes all split panes within every tab. This considerably increases the code overview and code maintenance. It makes it also much easier to extend the user interface with new components. As can be seen in the class diagram, there are two more classes. Class GUIMenuBar creates the programs menu bar. Class GUIToolBar creates a tool bar where users can reach often used functions faster. Tool bars can be seen in nearly every larger software that has a graphical user interface. They ease working with complex software, since tool bars map program function names to icons. The modularization of the user interface has several advantages. Both components, the menu bar and the tool bar are relatively complex user interface components. Both contain several other components and a lot of own functionality. Thus, it is better to encapsulate this functionality within an extra class. The menu bar and the tool bar have a lot of similar items. While the menu bar has a set of menu items, a tool bar has several buttons. All menu items are created in the same manner. A menu item can have text to display, an icon and may be enabled or disabled at start. The same applies to buttons for the button bar. Therefore, this algorithm was put into own methods. This makes source code reading much easier, also modifications are much easier to make. To create menu items, GUIMenuBar has the method createJMenuItem and GUIToolBar has the method createJButton for creating a new button to add to the tool bar. As can be seen in the class diagram, all three classes have an addListeners method. All needed event listeners for the graphical components of those classes are created within this method and added to the respective component. This also increases the overview on the source code. It is not necessary any longer to search the source code for the place where to add and change event listeners.

Figure 23. Class diagram of main components of the new graphical user interface.

Class diagram of main components of the new graphical user interface.

The three user interface classes shown in the class diagram must communicate with each other. The main class GUI holds an instance of the tool bar class and the menu bar class. The menu bar class and the tool bar class on the other side have the current instance of the main class. With this architecture, it is possible that different methods of the main class can be invoked when the user chooses a menu item or clicks on a button. For instance, simulation source code creation and compilation or simulation execution can be invoked from the menu bar and also from the tool bar. The tool bar and the menu bar also have a lot of useful functions that can be used like opening simulation files or project files for instance. All these menu items or tool bar buttons will also invoke methods of the main class. The other way round, the class GUI also needs to invoke methods of the tool bar and the menu bar. Several buttons or menu items must be enabled or disabled depending on whether they should be selectable or not. For instance, the run button should not be selectable before simulation files have been compiled.

Besides the new user interface architecture, a lot of useful functions have been implemented to enhance the user interface. These will only be mentioned here. To improve the work with the simulation files, the XML input files can be modified directly via the user interface. This is very important if developers what to test different simulation scenarios and don't want to use an external XML editor parallel to AOR-JSim. To check the XML files, the user can validate them against an XML Schema file. It is also possible to modify the generated Java sources. This can be useful for experienced users to implement extra simulation code that cannot be generated directly. Generated simulation output can be saved to a file with the current simulator version. This can be done either directly during a running simulation or after the simulation has ended. Another extension to the user interface is the display of the last used simulation and project files. With this feature, users can load last used files faster without the need to search for them with the help of a file chooser. The next new feature is a progress bar, that is used to display the compilation and simulation execution progress. This lets the user of the program follow what currently happens.

The last new feature to mention here, is the integration of a help system. This help system can directly be accessed from the program. It contains help texts about using the program and help text about the XML language used for Agent-Object-Relationship Simulation: AORSML. The help system uses the JavaHelp architecture from Sun Microsystems [JHLP07]. The help texts are written in HTML. For connecting several help texts, a table of contents file must also be created as well as a file for mapping help menu names to real help files. The rest, including a search possibility, will be created from the help system itself. Thus, using the JavaHelp system makes it very easy to create help texts and to include them into an application.

4.4. Java Code Generation

An advantage of Agent-Object-Relationship simulations is that they can be defined in a higher level language. Thus, an AOR simulation developer doesn't needs to know a programming language. But, the XML based simulation files cannot be executed directly. First it is necessary to generate program code with the information from the XML files. AOR-JSim creates Java classes that derive from a set of abstract AOR classes. Every abstract class in turn has a set of abstract methods that must be implemented. This ensures that every generated simulation can be executed in the same way automatically with the simulator. This section shows how this is done in practice.

The generation of Java code from AORSML is done in several steps. The whole process will be explained by means of the creation of an agent rule class from its AORSML description. The next listing shows a part of the Beer Game AORSML file with the definition of an agent rule for the delivery of beer to a supply chain node. The rule ensures that the delivered quantity of beer will be added to the inventory of the agent.

<AgentRule name="RuleIncomingBeerDelivery">
  <triggeringEventExpr>
    <AtomicEventExpr eventName="BeerDelivery" alias="beerDelivery"/>
  </triggeringEventExpr>
  <involvedPhysicalObject>
    <Agent type="SupplyChainNode" alias="node"/>
  </involvedPhysicalObject>
  <stateEffects language="Java">
    <assign property="node.inventory" 
            valueExpression="node.inventory + beerDelivery.quantity"/>
  </stateEffects>
</AgentRule>

If the AORSML file is opened within AOR-JSim, the user can press the generate button to start the Java code creation. Figure 24, “Diagram of involved classes for code generation.” shows the involved classes of the whole process. Classes JavaSourceCodeCreator and XMLClassWrapper are basic classes that stand representatively for several derived classes. The diagram also shows an example for each of the two classes that are used to create the agent rule Java file.

Figure 24. Diagram of involved classes for code generation.

Diagram of involved classes for code generation.

Internally, after pressing the generate button, method generateJavaFiles in the main class GUI of the simulator is now called and a new instance of ClassesCreator will be created. The current AORSML file is passed as argument to the class constructor and then parsed to create a new Document object. This object now contains all nodes that are included in the AORSML file. Since every entity of the AOR language has a different structure, there are appropriate source file and wrapper implementations for all entities. Thus, for a further processing it is necessary to divide the document and create lists of equal nodes, e.g., a node list with all agents or all actions etc. This is done with the class AORSMLSplitter. The class uses a resource bundle to search for nodes in the document tree. This is a property file that contains search strings as keys and value strings to indicate the path within an XML tree. Using a resource bundle has a simple reason. For finding the right information of a node, the simulator usually needs to know the file structure of AORSML. Thus, after making a change within the language, like changing the name of an attribute for instance, it would be necessary to re-compile the whole simulator. To avoid this effort, the structure of all AORSML nodes is described with such a resource bundle. Now, it is only necessary to adapt the resource bundle file for smaller changes of the language. The following listing shows a part of the property file with some key - value pairs for entity definitions and for an agent rule.

aorsml.event.causedevent = AORSML/Classes/CausedEventType
aorsml.message           = AORSML/Classes/MessageType
aorsml.agent             = AORSML/Classes/AgentType
...
aorsml.agentrules                  = AORSML/Rules/AgentRule
aorsml.rule.resulting              = ./resultingEventExpr/AtomicEventExpr
aorsml.rule.resulting.name         = @eventName
aorsml.rule.resulting.type         = @eventType
aorsml.rule.condition              = ./condition
aorsml.rule.involvedPhysicalObject = ./involvedPhysicalObject

After the document was divided into node lists, class ClassesCreator calls the method createClassesFromDocument for further processing. This method calls different creator methods where every method is responsible for a certain AOR entity. After getting the list of nodes containing XML elements of agent rules from class AORSMLSplitter, a new instance of an AgentRuleSourceFile is created for every node. This class creates the Java source code for an agent rule. Every source file class uses a wrapper class that first searches for the specific data of an entity like name, properties or everything what is needed for an entity. For an agent rule, class AgentRuleWrapper searches for the triggering event, involved objects or agents, a condition phrase or some state effects. The resource bundle described above, is again used to search for the information within the XML node. After this is done, the source file class can create the source code. Every single method of the new class now gets assembled for that purpose. The next listing shows a method from AgentRuleCreator that assembles the state effects method as an example.

private StringBuffer createStateEffectsMethod() {
  StringBuffer method = new StringBuffer();
  method.append(TAB+"public void stateEffects() {\n");
          
  if (agentRuleWrapper.stateEffects != null) {
    for (int i=0; i<agentRuleWrapper.stateEffects.length; i++) {
      int indexDot = agentRuleWrapper.stateEffects[i].getName().indexOf('.');
      String alias = agentRuleWrapper.stateEffects[i].getName()
                     .substring(0,indexDot);
      String var = agentRuleWrapper.stateEffects[i].getName()
                   .substring(indexDot+1);
      String firstChar = var.substring(0, 1);
      String newVar = firstChar.toUpperCase() + var.substring(1);               
      method.append(TAB+TAB+alias+".set"+newVar+"("
                    +agentRuleWrapper.stateEffects[i].getValue()+");\n");
    }
  }
  method.append(TAB+"}\n");
  return method;
}

The method uses a string buffer and appends line for line of the new method. This always starts with the method head declaration, here "public void stateEffects() {". After this, the body of the method is created. For the state effects method, it is first necessary to check if there are state effects for this rule. If so, a line for every state effect gets assembled. Before creating the assign line, it is necessary to change the property name string from the AORSML file. As can be seen in the AORSML sample above, the property that shall be assigned has the form "agent-alias.property-name". For using the life statistics functions of the simulator, it is necessary to use the set-methods for changing an agent or object property. For instance, for changing the property inventory of a supply chain node, the setInventory method must be used instead of directly assigning a new value. Thus, every state effects variable will be split up to "agent-alias" and "property-name" and the first character of the "property-name" gets changed to upper case. Finally after creating all methods, the whole Java class can be assembled. The listing below shows an extract of the agent rule that was created from the AORSML shown above.

public class RuleIncomingBeerDelivery extends AgentRule { 
  public BeerDelivery beerDelivery; 
  public InternalAgentSupplyChainNode node; 
  
  public RuleIncomingBeerDelivery(InternalEventType e, InternalAgentType a) {
    beerDelivery = (BeerDelivery)e;
    node = (InternalAgentSupplyChainNode)a;
  }
...
  public void stateEffects() {
    node.setInventory(node.inventory + beerDelivery.quantity);
  }
}

4.5. Running Simulations

AOR-JSim enables the execution of generated simulations directly within its program environment. The core function is based on the mechanism that was used in AbSim. But, the extension made to the simulator software also required to adapt this mechanism. Section 4.5.1, “Implementing a Special Class Loader” first describes the changes made to the execution. After this, Section 4.5.2, “Simulation Flow” shows the application flow of a running simulation.

4.5.1. Implementing a Special Class Loader

A fundamental condition for implementing player functionalities or enabling extensive loggers is the complete control over the simulation execution. Since the generated simulation classes are not known to AOR-JSim at compilation time of the simulator itself, there is no possibility to access them directly. Thus, the simulation must be executed with other means. Java provides two mechanisms of executing Java programs that are not known at compilation time. On the one hand, an application can access its own runtime environment to execute commands. Since the name and path of the main class of a generated simulation is known at runtime, it is possible to create some string like "java -classpath ... simulationname" and execute it. This returns an instance of the process within the simulation is running. The process itself returns the corresponding input and output streams. The input stream can be used to print the output of the simulation. This mechanism of running simulations is used by AbSim. There is one weak point in using this possibility of running simulations. It is not possible to access the simulation classes directly, for instance via method invocation. But, implementing player functionalities requires invoking methods of the simulation main class. Therefore, it is necessary to find another way of executing the generated classes.

As mentioned, there is a second mechanism in Java. With the help of class loaders it is possible to load a Java class from any source like a local path or some network connection. A class loader creates an instance of class Class from a given binary name. This class can then be accessed by casting it to the real class. The following listing shows how this is done with an URLClassLoader and a fictive class MyClass that is located in the fictive package mypackage. The class loader first must be initialized with an array of paths that are used to search for the desired classes. After initializing the class loader, it can be used to load classes from the given paths. Lines 8 and 9 show the basic usage. The loadClass method tries to find the class and, if this succeeds, returns an instance of the class object of the desired class. Finally, calling newInstance creates an object from this class. This can then be used like any other object; for instance one might cast it to the real object like line 11 shows.

try {
  String searchPath = ... ;

  java.net.URL url = new java.io.File(searchPath).toURI().toURL();
  java.net.URLClassLoader cl 
      = new java.net.URLClassLoader(new URL[] {url} );

  Class myClass = cl.loadClass("mypackage.MyClass");
  Object myObject = myClass.newInstance();
  
  MyClass myClassInstance = (MyClass)myClass;
} catch (Exception e) {
  // do something in case of an error
}

In deed, the described mechanism works pretty well. But, there is one weak point for using it with AOR-JSim. The class loader will always try to look first if the class has already been loaded before. In this case, the loadClass method just returns the class object from it's memory. This mechanism was implemented for performance reasons to speed up Java programs. The disadvantage of this approach is, that if a class changes during runtime, always the first loaded version will be returned by the class loader. Since it is possible to edit a AORSML file within AOR-JSim, the generated classes might change as well as the compiled class files. Nevertheless, a standard class loader would always create an instance from the first version that was loaded. And there is no possibility to change the behavior when using standard class loaders. Editing the simulation file within the simulator and then compiling it, would have no effect on the simulation execution. The executed version would always be the very first executed version. Only restarting the simulator would help to avoid this. Logical, that this is no satisfying solution.

To solve this problem, a new class loader called CustomClassLoader is implemented. This class loader is based on the URLClassLoader shown in the listing above. It simply overrides the loadClass method to load all desired classes directly from the file system. This ensures that it is possible to make changes at an opened AORSML file, compile the generated classes and finally run this new version. For performance reasons, it is still possible to use a standard class loader in the case, that a simulation gets played several times without being compiled again. The following listing shows the relevant source code extract. After creating the URL object with the current path, it will be checked whether the class files must be loaded from the file system or not. This is done with a check if there are new simulation files, as can be seen in line 6. Then, after successfully loading the main simulation class, it is possible to invoke methods on it. In the example below, line 17 shows how to start the simulation by invoking the simulate method. As can be seen, before invoking the method, the object must be casted first to the SimulationSystem class. Finally, it is possible to invoke methods on the simulation class. In the example, the method invocation for starting the actual simulation is shown. But there are also other methods that can be invoked before simulation start, like setting a logger or changing some simulation properties.

try {
  URL url = new File(ProjectState.getProperty("user.dir")
                     +File.separator).toURI().toURL();
  Class simClass = null;
              
  if (gui.getNewSimulationFilesStatus()) {
    CustomClassLoader cl = new CustomClassLoader(new URL[] {url} );
    simClass = cl.loadClass(ProjectState.getProperty("user.dir")
                            +File.separator+packageName+File.separator, 
                            simName);
  } else {
    URLClassLoader cl = new URLClassLoader(new URL[] {url} );
    simClass = cl.loadClass(packageName+"."+simName);
  }
  Object simObject = simClass.newInstance();
  ...
  ((aorsimulation.SimulationSystem)simObject).simulate();
  ...
} catch (Exception e) {
  // do something in case of an error
}

4.5.2. Simulation Flow

After invoking the simulate method on the simulation system main class, the simulation starts running. If not paused or stopped externally from the user interface, the simulation will now run until it's natural ending[22]. The simulation will always run the same cycle. Since the simulation cycle is a complex process, the description will be split into three sections. To start, Section 4.5.2.1, “Main Simulation Cycle” describes the rough process. The next section explains the environment simulator step in detail. Then, Section 4.5.2.3, “Agent Simulator Cycle” illustrates an agent simulator step in detail. The final section then describes changes and improvements made in the simulation flow for Agent-Object-Relationship Simulation in comparison to the given Agent Based Simulation flow.

4.5.2.1. Main Simulation Cycle

The main cycle of the simulation process is an interaction of the simulation system main class with the environment simulator and all agent simulators. The simulation system main class is hereby some kind of control instance, that is necessary to ensure the simulation flow between the environment simulator and all agent simulators. It does not act in relation to an Agent-Object-Relationship simulation[23]. As can be seen in Figure 25, “Simulation flow activity diagram.”, every cycle starts in class SimulationSystem by calling the internal method environmentSimulatorStep (1). This method forces the environment simulator to simulate one environment cycle. The set of current agent actions and agent messages is hereby passed to the environment simulator (2). The simulator uses these events to compute a new environment state (3). This will be explained in detail in Section 4.5.2.2, “Environment Simulator Cycle”. The externally visible result of an environment simulator step is a set of new perceptions as shown in step (4). The simulation system receives this set and assigns the perceptions to the respective agent that should receive the perception. This is possible, since every perception has a property that holds the identifier of the receiving agent and a property for the class type of this agent. After assigning all perceptions, the simulation system main class forces every agent simulator to do another simulation step (5). Every agent simulator then creates two new sets of actions and messages[24] as a reaction of those given perceptions and transfers these actions and messages back to the main class (6). Finally, the main class of the simulation checks whether there are more events to be simulated in a future cycle. If there are future events, the whole process will start again from the beginning. If not, the simulation comes to an end.

Figure 25. Simulation flow activity diagram.

Simulation flow activity diagram.

4.5.2.2. Environment Simulator Cycle

The environment simulator processes all actions that agents do and all messages that agents send. Beyond this, the environment simulator also processes exogenous events that influence a simulation from outside[25]and caused events from previous cycles. Figure 26, “Environment simulator cycle.” shows the complete environment simulator cycle. While actions and messages are transferred from the simulation system main class at the beginning of each cycle, exogenous and caused events are stored directly at the environment simulator. Before starting a cycle, the environment simulator must therefore check all previously stored events[26] if one or more of them should be simulated in the current simulation cycle (1). This is the case, when their occurrence time is not larger than the current simulation time. The events will then be stored in a set that automatically sorts all events to maintain the causality. The event with the smallest occurrence time is the first in the set that will be be simulated (2). Now, the control flow is given to the simulate method of the environment event. To simulate an event, there is a set of rules for every event that specify what should be done if the event occurs. To start simulating this event, the first rule from this set is taken (3) and a condition will be checked to see if the event applies[27] (4). A rule must not coercively define a condition. If no condition is defined, the rule will always be applied. If the condition is not true, the next rule will be taken. Otherwise, all resulting events are generated (5). An environment rule has two methods for generating resulting events. The first returns a set of resulting environment events, for instance events of type CausedEventType. These are used in a future environment simulator step. The other method creates a set of resulting perceptions. This includes message perceptions that indicate the reception of a message. The next part of an environment rule execution is invoking methods that might create or destroy new agents or objects (6). Finally, a rule processes effects on the state of agents and objects from the given event (7). When there are more rules (8) the cycle will start again with the next rule. New resulting events or perceptions are then added to the already created event sets. After all rules are processed, the result, containing resulting events and perceptions, is returned to the environment simulator and added to a complete environment simulator step result. After this is done with all events (9), all caused events are taken from the result and stored for future steps (10). Then, at the end of the simulation step, the environment simulator returns the set of new perceptions to the simulation system main class.

Figure 26. Environment simulator cycle.

Environment simulator cycle

4.5.2.3. Agent Simulator Cycle

After the environment simulator has finished the current simulation step, the simulation system calls all agent simulators to simulate the next internal step for the agent they control[28]. These calls are synchronous. That means, the simulation system calls an agent simulator, waits for the result, then calls the next agent simulator a.s.o. This mechanism has the advantage that it is possible to create XML based output for all agent simulator steps. An asynchronous, e.g., thread based, architecture could not ensure a fixed sequence of agent step processing. Nevertheless, Section 6.1, “Introducing a Multithreaded AOR-JSim Version” will introduce a multithreaded version of AOR-JSim, that shows a nice feature of using thread based agent simulators.

To illustrate an agent simulator step, see Figure 27, “Agent simulator cycle.” for an activity diagram of the complete cycle. As can be seen, the simulator receives a set of new perceptions at cycle start (1). These perceptions have been the result of the last environment simulator step. Every agent simulator logically only receives perceptions that his agent should perceive. Incoming messages are hereby perceived as message perceptions; thus, they are included in the received perception set. Before simulating any of these new perceptions, the agent simulator checks if there are reminder events from previous cycles that should occur in the current cycle. Finally, the set of periodic time events will be checked for events for the current cycle. After the set of current events is created, the event with the smallest occurrence time is taken out of the set to simulate it (2). The event simulation will be processed by the event itself after it's simulate method was invoked. To start, all known rules for this event are taken and processed one after the other (3). The first step is always the check for the optional rule condition (4). As mentioned in Section 4.5.2.2, “Environment Simulator Cycle”, it is possible to define constraints with these conditions under which a rule should apply. And, this is especially important for agent rules. For instance, it is possible that all agents use the same periodic time events as for the EndOfWeek event in the Beer Game that controls several actions. To let agents react different on the same event or to not use one of the events rules, if there is more than one, it is possible to simply define some condition phrases for these rules. If the condition is true or no condition is defined, the rule will be applied. If the rule is used for the event, three sets of new events are created: one for new actions, one for messages to send and the third for new resulting time events (5)[29]. If there are for instance no actions this agent will take, an empty set is created. At the end of the processing of the rule, a method for changing the state of the agent is invoked (6). This is necessary in case that some of the agent's properties are involved by the incoming or some of the outgoing events. For example, if an agent in the Beer Game received a new beer order, its property that counts the ordered beer amount will be incremented by the new received quantity. Another example is, that if this agent ships beer to another agent, the amount of beer from this new action event must be subtracted from the agents inventory and ordered quantity properties. After the current rule was successfully processed, the next rule is taken and processed. This will be repeated until all rules that apply to the given event are processed (7). The result of every rule will be combined to a complete rule result. Then, if there is another event in the current simulation cycle (8), this event will also be simulated. Finally, the agent simulator stores all new reminder events for future steps (9) and returns the set of new created actions and messages from this agent to the simulation system (10). After all agent simulators returned their current step results, the simulation system sends all these results to the environment simulator to start the next simulation step.

Figure 27. Agent simulator cycle.

Agent simulator cycle

4.5.2.4. Simulation Flow Extensions and Improvements

The simulation flow presented in this section is based on the simulation flow of the Agent-Based Simulation System. To use it for Agent-Object-Relationship Simulation, only few changes were necessary. After changing the names of the AbSim classes to the class names of the AOR entities, the basic process could get simulated. But, there are still some changes to extend and improve the simulation flow. First, the sequence of creating resulting events and executing state effects was exchanged. In the original version, the creation of resulting events was the last part in a rule simulation, after invoking the state effects method of the rule. But, it is more logical the other way round. The reason is, that a resulting event can also have an effect on an agent. For instance, in the Beer Game simulation, a resulting beer shipping action has an influence on the inventory and ordered quantity properties of the agent. Thus, they must be changed after the new resulting action was created. For that reason, the sequence of rule processing was changed, so that first all resulting events are created and after this, all state effects are made. The next thing to improve is the processing of the complete set of event rules. In the original version, only one rule could be applied to an event. This means, if there are several rules for the same event in an AbSim simulation, the first matching rule creates the result of this event's simulation. After this, the event simulation process stops. In fact, this way seems logical. But, as the Beer Game simulation shows, one event can cause a lot of different things. For instance, the EndOfWeek event can result in a beer shipping action, the ordering of new beer and the calculation of the costs of a supply chain node. By including all this in one single rule, the simulation script would hardly be readable. Thus, it is better to allow multiple rules to be used for one event at the same time. To realize this, all rules of an event are checked if their condition is true and then processed iterative. The result of every processed rule is added to a complete result of all rules. After all these rules have been executed, the combined result is returned. Beyond this, there is another extension to the environment simulator flow, that was necessary due to simulation language development. To allow more complex simulations, the creation and destruction of agents and objects at simulation time was included into the AOR language. Like creating resulting events or executing state effects, this feature is also included into rule processing. There is a set of abstract methods within environment rules that must be implemented to create or destroy a physical object. These methods are then invoked when an environment rule gets processed. Thus, the invocation of these methods is included in the environment simulator flow.

Finally, an improvement of the Java code was made. The original simulator AbSim used several classes for storing sets of events: a class for storing actions, a class for storing messages, one for internal events and one for environment events. All these classes are nearly equal. They all use a sorted tree set for storing events. All these classes have the same methods that simply invoke methods on the used sorted set, but they do not inherit from the set class. Since all these set classes have the completely same structure and behavior and only differ in the type of events to store, it was obvious to create one single set class that could be used for all types of events that are used in AOR simulation. This new class EventSet not only uses a sorted tree set, it also extends the TreeSet class from the java.util package. Thus, all methods of class TreeSet can be invoked directly on this EventSet class. To enable using this set for all kinds of events, there had been two possibilities. The TreeSet class belongs to the Java Collections Framework and can be used for every kind of Java class. Thus, using this already enables using it for all events. A disadvantage of this solution is, that it is necessary to cast a retrieved object from the set to the class type of the event that was inserted in the set. Since Java version 5, it is possible to create more safe code by using generic data types. This means, it is possible to create a class that can be used with all kinds of Java objects on the one hand but it is possible to define the type of class that will be used for a certain instance of this class on the other hand. Thus, defining the type of class ensures also to retrieve exactly these classes and no class cast is necessary. The next code listing shows an extract from the created EventSet class and a usage example to illustrate the improvements. The <E> is the type parameter that can be used to set a certain type of class to be used with the set. By the way, it is still possible to use the class without declaring a type. As can be seen in lines 18 to 21, by specifying to use the set with environment events for instance, the set class guarantees that all returned object are from type EnvironmentEvent. Thus, this new event set class is now the only event set class to be used with the simulation system, but also ensures a safe source code by using typed parameters.

public class EventSet<E> extends TreeSet<E> {
  public EventSet(Comparator c) {
    super(c);
  }

  public void addEvent(E e) {
    this.add(e);
  }

  public E extractMin() {
    E e = this.first();
    this.remove(e);
    return e;
  }
  ...
}
...
EventSet<EnvironmentEvent> currentEvents = 
  new EventSet<EnvironmentEvent>(new EventTypeComparator());
...
EnvironmentEvent e = currentEvents.extractMin();

4.6. Creating Project Files

For improving the usability of AOR-JSim, it is necessary to introduce the possibility of saving a current project state. In fact, the AbSim simulation system, AOR-JSim is based on, has an option to save and open projects, but this function does not work correctly. AbSim seams to store some path information about the original file that was opened and an already transformed AbSimML file. But, after re-opening the project, the software does not completely restore the original state of the program of the point in time the project was saved[30]. Thus, it is necessary to implement a new possibility of collecting information of a project and making it possible to completely re-store a project.

A project file must include all simulator settings a user can change plus information on the current state of the project. For instance, a user might want to run a simulation more often without wanting to wait some time for generating Java files and compiling them ever and ever again after restarting the simulator. Thus, all information that is needed to restore a certain state of the simulator must be collected and saved to a file. This section shows how this can be done. First, Section 4.6.1, “Relevant Project State Information” explains what information is necessary to restore a project completely. After this, Section 4.6.2, “Project File Structure” shows the creation and structure of a project file. The code listings in this section are extracts from a project file that was created with the simulator.

4.6.1. Relevant Project State Information

Before starting to create a project file, it is necessary to figure out what information is needed to fully restore a project. There are two main kinds of project information. The first includes information on the actual state of the program: current settings and the state of the simulation creation. The other includes information on the simulation itself. Current settings only include some simple properties, that the program uses. The following shows a selection of some program settings:

  • AOR-JSim version[31]

  • text / code indent

  • AORSML XML Schema file

  • currently used logger class

  • size and location of the main window of the user interface

  • visibility and size of system output panel

As mentioned, it is also necessary to store the state of the simulator. That means, for instance, if a user has already compiled her simulation Java files, she also wants to be able to directly start a simulation run after re-opening the project. Figure 28, “Possible states of AOR-JSim.” shows a diagram with all possible main states and transitions between them. After opening an AORSML file, the user must first start the generation of Java code from the given input file. After this is finished, it is possible to compile the generated code. Finally, after the generated Java code was compiled successfully, the simulation can be executed. See sections Section 4.4, “Java Code Generation” and Section 4.5, “Running Simulations” for detailed information on these processes. To restore the states isGenerated and isCompiled, it is enough to save some kind of flag that indicates if the state was already reached or not. In addition to this, it is also necessary to save the name and path of the simulation file to cover the first state of the simulator after the initial state.

Figure 28. Possible states of AOR-JSim.

Possible states of AOR-JSim.

Beyond the program state, it is necessary to figure out what information is relevant to restore the AOR project. After generating the Java code, AOR-JSim offers a tree view on all created classes. The screenshot depicted in Figure 18, “Screenshot of AOR-JSim.” shows this tree on the left side. This tree displays the different entity types, e.g., agents, events or rules in hierarchical order. By clicking on a leaf of the tree, the user can see and edit[32] the generated source code. To restore a project, it is therefore also important to recreate this tree structure. This means, on the one hand, to rebuild the tree, it is necessary to assign the names of the generated classes to the entity types. On the other hand, the source code of the generated classes must also again be available after opening a project. Thus, when saving a project, the generated classes must also be saved and the project file must contain the path information plus a list of all entity types with the information which generated class belongs to which entity.

4.6.2. Project File Structure

The necessary project state information described above, can easily be presented as a list of property value pairs. With Java it is very easy to manage properties by using the Properties class. This class inherits from Hashtable and maps property name strings as keys and property values strings as values. Two different output formats are supported by this Properties class. The first is a simple text format, the second one is XML based. AOR-JSim uses the XML formatted version, since it might be possible in the future that there will be implementations of an AOR simulator in other languages that can use the same project files [33]. The structure of XML based Java property files is pretty simple. The main element properties consists of one or more elements of type entry. While the property string is assigned by setting the attribute key, the value string of a property is the text content of the entry element. The following code lines show the basic structure of such a property file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
  <entry key="...">...</entry>
</properties>

As described in Section 4.6.1, “Relevant Project State Information”, the content of an AOR-JSim property file can be divided into a part for program settings including its current state and a part for information about the current AOR project. To distinguish between both parts of the project settings, the project names use two different key words. Properties starting with aorgeneration describe AOR-JSim state information and other AOR-JSim settings. The key word aorsimulation associates properties for the current AOR project. As the listing below shows, the first part contains information like the used schema file for validating the AORSML files, the size and location of the main window or the last active program tab. To be able to restore the state of simulation generation, there are two state settings aorgeneration.state.isGenerated and aorgeneration.state.isCompiled. Both can only take the boolean values true or false. Thus, the project in the example below was already generated but not yet compiled.

<entry key="aorgeneration.aorjsim.version">AOR-JSim 0.23.1</entry>
<entry key="aorgeneration.aorjsim.bounds">100/100/1000/800</entry>
<entry key="aorgeneration.aorjsim.sysstreamvisible">true</entry>
<entry key="aorgeneration.aorjsim.mainsplitdivider">600</entry>
<entry key="aorgeneration.schema">aorsml.xsd</entry>
<entry key="aorgeneration.package">AOR-JSim.jar</entry>
<entry key="aorgeneration.state.isGenerated">true</entry>
<entry key="aorgeneration.state.isCompiled">false</entry>
<entry key="aorgeneration.indentsize.java">4</entry>
<entry key="aorgeneration.activetab">3</entry>

A large part of the project file is used for information on the current state of the AOR simulation. For instance, this includes information on the name and path of the AORSML file and the name of the simulation package. As described before, to restore the classes tree that enables viewing and editing the Java code inside AOR-JSim, it is also necessary to store information on the types of classes that are included in the simulation. Indeed, the information of the simulation package is sufficient for loading all generated classes from the file system, but this is not sufficient for categorizing them into the different AOR entity types[34]. Thus, the project file also contains properties that allows the simulator to restore this. The next listing shows some of these simulation properties.

<entry key="aorsimulation.simulationpackage">beergame_v1</entry>
<entry key="aorsimulation.aorsml">D:\...\BeerGame_v1.xml</entry>
...
<entry key="aorsimulation.System">BeerGame_v1</entry>
<entry key="aorsimulation.Agents">
  SupplyChainNode InternalAgentSupplyChainNode
</entry>
<entry key="aorsimulation.Events.ReminderEvents">EndOfWeek</entry>
<entry key="aorsimulation.Actions">ShipBeer</entry>
<entry key="aorsimulation.Rules.EnvironmentRules">
  RuleCreateShippingDelay RuleShipBeer RuleCustomerDemand
</entry>
...
<entry key="aorsimulation.stopTime">28</entry>
<entry key="aorsimulation.cycleDuration">7</entry>

The first two lines specify the name of the classes package and the complete path of the AORSML file. The following lines contain the properties for mapping the file names to AOR entity categories. Classes of the same entity type are combined to one single content part of the entry element. They are separated by a blank. Finally, there are some properties for executing the simulation, for instance a value for the stop time and the duration of a simulation cycle.

After opening a project file, accessing the property values is easy. As mentioned, the Properties class inherits from Hashtable and maps string keys to string values. Thus, to get a property value it is only necessary to search for the right property string. Most values just have to be converted to their actual type, like boolean or integer. Then the corresponding internal fields can be assigned with these new values. Some of these values are also used to adjust the user interface to display the new state. This means, for instance some buttons must be enabled or disabled or the last opened tab at project saving time will be set visible. To restore the generated Java classes tree, it is first necessary to get the names of all generated classes from the project file. After this, the source code from each class must be loaded and assigned to the source code object. Finally, the tree structure will be recreated. After this is done, the project is completely restored and the user can continue working at the same point where she saved the project.

4.7. Creating Structured Simulation Output

To evaluate simulations results, it is necessary to collect all relevant data during a simulation run and to present it in a form that can easily be used for post processing. Since it is not known to AOR-JSim at simulation execution what data might be interesting to a user, it is necessary to log the whole simulation progress. The AbSim simulation system already introduced a possibility to log the simulation progress. It uses an abstract class with a set of abstract methods that the simulation classes invoke during a running simulation. Based on this abstract class, an interface is developed to collect simulation data. This interface will be presented in Section 4.7.1, “Introducing an Interface to collect Simulation Data”. The following section shows an implementation of this interface that generates an XML based log file. Finally, Section 4.7.3, “Implementing an Easy-Plugging Logger Architecture” presents a way of easily plugging further logger implementations to AOR-JSim.

4.7.1. Introducing an Interface to collect Simulation Data

Since AOR simulations run in a closed system independent[35] from the simulator, it is necessary to create some feedback possibility to collect simulation progress data. An interface between AOR-JSim and the simulation system seems to be an appropriate solution. The simulation system hereby only knows the interface to send data to, but from outside, it is possible to use an implementation of this interface that forwards this data to the simulator. This way, the simulation system is still independent from the generator software. Figure 29, “The embedding of the logger interface.” shows the class structure of this architecture. The figure shows two interfaces, class SimulationLog and class AORJSimLog. The first is a basic interface that contains a set of notification methods for different simulation processes[36]. The simulation system, the environment simulator and all agent simulators have an instance of the current logger. At simulation runtime they call the appropriate notification method whenever a new simulation step starts, an event occurs, a rule is processed and so on. An implementation of this interface now can process the given information. As can be seen in the figure, there is another interface that inherits from SimulationLog: AORJSimLog. This interface only has one method: setGUI. This method sets the instance of AOR-JSim to a logger. Implementations of the logger interface that will be used with AOR-JSim and want to send output data back to the simulator should use the inherited version. The division into two logger interfaces has one simple reason. Since the simulation system is a separate package, it is also possible to run simulations without AOR-JSim. For this case it is necessary that the logger interface doesn't imports any classes from the package aorgeneration, that also contains the main class GUI. Thus, there is one basic interface that already contains all notifier methods and one specialized interface that can be used to send data back to the user interface.

Figure 29. The embedding of the logger interface.

The embedding of the logger interface.

4.7.2. Creating an XML based Output File

For easy post processing of simulation progress data, it is necessary to implement a simulation logger that creates output in a well structured format. To offer high compatibility, the decision was to create an XML based language for logging the simulation data. XML has a well formed structure, is also easy to read and there are a lot of software tools that can work with XML based files. Furthermore, for a lot of programming or scripting languages there are free libraries for processing XML documents. Thus, an XML based output format also makes it easier to create own software solutions that might process AOR simulation output. This section shows in the following how the created output is structured and what information is inserted and how this is done. This section is divided into two sub sections. The first introduces the logger implementation. After this, the second sub section shows the XML output language structure.

4.7.2.1. An Custom Logger Implementation

As mentioned in the section before, the logger class has a set of notification methods that are called from the simulation system as well as from the environment simulator and all agent simulators at runtime whenever something happens in the simulation. This can be the start of a simulation step, a new event, a new simulation state or some other occasion. To create the appropriate XML output, these methods must be used to print the structured information. The XML output is hereby a mixture of predefined strings containing key tags and attribute names and strings that are generated and inserted at runtime. The listing below shows an extract from the created XML logger implementation XMLLog. As can be seen, some of the notification methods have arguments covering additional information. This may be the name of the simulation or the instance of a new event that has been created. The first method shown below, is used to print the opening tag of the root element of the output file. The most part is predefined output text, like a namespace declaration. The listing also shows a schema definition. The schema aorout.xsd was also created for this AOR XML output language. Thus, these output files can also be validated. See Appendix E, XML Schema for Simulation Output Language for this schema. Line 7 of the listing shows an example where some additional information is inserted in the XML. Here, it is simply the name of the simulation as been given in the argument of the method.

public void notifyStart(String simName) {
  printOutput("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n");
  printOutput("<SimulationOutput "
              + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n"
              + "xmlns=\"http://aors.info\"\n"
              + "xsi:schemaLocation=\"http://aors.info aorout.xsd\"\n"
              + "simulationName=\""+simName+"\">\n");
}
...
public void notifyEnd() {
  printOutput("</SimulationOutput>\n");
}
...
public void notifyEnvironmentRuleEnd() {
  printOutput(TAB+TAB+TAB+TAB+"</EnvironmentRule>\n");
}

As mentioned before, the logger interface, that was the basis for the XML logger, was developed from an abstract class that was used for AbSim to print some simple output. To create a real XML file, it is necessary to add a lot more notification methods. One reason is simply that AOR has a lot more simulation possibilities that must be reflected in an output file like creating new agents during a simulation run. Another reason is that the given methods are not sufficient to correctly create opening and closing tags. Thus, there is a set of new methods that enable printing closing tags to create well formed XML. One sample method is also shown in the listing above. This method simply prints the closing tag for an environment rule.

4.7.2.2. Output Language Specification

The structure of the output language is simple but sufficient to deliver all simulation information. The following listing shows the basic structure. The root element SimulationOutput contains a set of SimulationStep elements and has one attribute specifying the name of the simulation. Every SimulationStep element wraps the information about one step in a simulation. This element also has two attributes; the first to specify the internal simulation clock cycle. The second attribute indicates the time of the simulation at the given simulation cycle[37].

<SimulationOutput simulationName="BeerGame_v1">
  <SimulationStep clock="1" time="7 days">...</SimulationStep>
  <SimulationStep clock="2" time="14 days">...</SimulationStep>
  ...
</SimulationOutput>

The simulation system starts a new step by calling the next environment simulator step. After this, the simulation system calls all agent simulators to simulate the next internal agent step. While a step gets simulated, the state of agents or objects might change. All this information will be displayed inside one SimulationStep element. The next code example shows the structure of one simulation step element. As can be seen, there is an extra sub element for every agent simulator. Hence, every agent step element must specify two attributes, one for the type of the agent and one for the id of the agent. The final element SimulationState shows the state of all objects and agents after the current simulation step.

<SimulationStep clock="1" time="7.0 days">
  <EnvironmentSimulatorStep>...</EnvironmentSimulatorStep>
  <AgentSimulatorStep name="Retailer" type="SupplyChainNode" id="1">
     ...
  </AgentSimulatorStep>
  <AgentSimulatorStep name="Distributor" type="SupplyChainNode" id="2">
    ...
  </AgentSimulatorStep>
  ...
  <SimulationState>...</SimulationState>
</SimulationStep>

In every simulation step, the environment simulator takes the list of current events and simulates on event after the other. To simulate an event, the list of rules of this event is checked if one or more rules apply[38] to it. Every rule that applies will then be executed. The corresponding output reflects this order of processes as the following listing of an environment simulator step shows. In the example, an incoming message from an agent gets processed and a message perception for the receiving agent of this message is created. As can be seen in the example, the processed event wraps the rules element to show that this rule has been applied to this event. To make the output usable, it is also necessary to print all properties of triggering or resulting events. In this example, the output of the properties of the message is done in two steps[39]. First, all standard properties of the super class MessageType are printed. These are used as attributes of the Message element. After this, all properties of the instance of the actual message object must be printed. Since the argument of the notify method can only be the super class of a message, event, action or perception, these fields of the class cannot be accessed directly. Here, it is necessary to use the Reflection Layer from Java. With reflection it is possible to read all fields declared in a class without knowing them at compile time. In the resulting XML there is one Slot element for every field that was found.

<EnvironmentSimulatorStep>
  <Message type="Order"
           senderType="SupplyChainNode" senderID="3"
           receiverType="SupplyChainNode" receiverID="4">
    <Slot property="quantity" value="9"/>
    <EnvironmentRule name="aorsimulation.environmentsimulator.MessageRule">
      <ResultingEvents>
        <MessagePerception type="Order" 
                           senderType="SupplyChainNode" senderID="3"
                           receiverType="SupplyChainNode" receiverID="4">
          <Slot property="quantity" value="9"/>
        </MessagePerception>
      </ResultingEvents>
    </EnvironmentRule>
  </Message>
  ...
</EnvironmentSimulatorStep>

Furthermore, environment rules can result in the creation or destruction of agents or objects. To reflect this, there are the following sub elements for the EnvironmentRule element:

  • CreateAgent

  • CreateObject

  • DestroyAgent

  • DestroyObject

The following lines show the structure of these elements. The CreateAgent and CreateObject elements are nearly equal except that agents can have self belief properties. Thus, the CreateAgent element can also contain the element SelfBeliefSlot. Both elements have three attributes specifying the given name, the class type and the id of the agent or object. The elements DestroyAgent and DestroyObject have no sub elements. They only contain the type and id of the physical object that was drestroyed.

<EnvironmentRule...>
  ...
  <CreateAgent name="..." type="..." id="...">
    <Slot property="..." value="..."/>
    <SelfBeliefSlot selfbeliefproperty="..." value="..."/>
  </CreateAgent>
  ...
  <CreateObject name="..." type="..." id="...">
    <Slot property="..." value="..."/>
  </CreateObject>
  ...
  <DestroyAgent type="..." id="..."/>
  ...
  <DestroyObject type="..." id="..."/>
</EnvironmentRule>

After the environment simulator finished the current simulation cycle, all agent simulators compute their current simulation step. There is one AgentSimulatorStep element for every agent simulator that participates in the simulation. As can be seen in the next listing, the structure of this element is equal to the structure of the EnvironmentSimulatorStep element. Every simulated event wraps the list of rules that have been applied to this event. The only difference is the naming of the sub elements. Since agents process internal events, messages and perceptions by using agent rules, there are the elements InternalEvent, Message, Perception and AgentRule. As the next listing of an agent simulator step shows, all event properties are also printed here.

<AgentSimulatorStep name="Retailer" type="SupplyChainNode" id="1">
  <InternalEvent type="EndOfWeek">
    <AgentRule name="RuleShippingAllCustomerOrders">
      <ResultingEvents>
      </ResultingEvents>
    </AgentRule>
    <AgentRule name="RuleOrderingStock">
      <ResultingEvents>
        <Message type="Order" 
                 senderType="SupplyChainNode" senderID="1" 
                 receiverType="SupplyChainNode" receiverID="2">
          <Slot property="quantity" value="3"/>
        </Message>
      </ResultingEvents>
    </AgentRule>
  </InternalEvent>
  <Perception type="CustomerOrder" 
              perceptorType="SupplyChainNode" perceptorID="1">
    <Slot property="quantity" value="4"/>
    <AgentRule name="RuleIncomingCustomerOrder">
      <ResultingEvents>
      </ResultingEvents>
    </AgentRule>
  </Perception>
</AgentSimulatorStep>

Finally, after printing all events and their corresponding rules of the current simulation step, it is necessary to print the current state of all agents and objects. This is the most important step, since this information might be the most interesting at all. For statistical evaluation of a simulation it will often be necessary to follow the developing of agent or object properties. For instance, this enables the possibility to compare the behavior of agents for different simulation scenarios. All new agent and object states are embedded in the element SimulationState. This, as can be seen in the next code listing, has the two sub elements Objects and Agents. In deed, agents and objects are processed by the same notify method, so the output is already sorted without the two elements. But for a large amount of agents or objects, this increases the readability of the output file, more than ever if the XML viewer software allows collapsing of elements. Both, the agent and the object element, have the three attributes: name, type and id. The first attribute is the name that the simulation description developer has chosen for a physical object. It has no direct meaning for the simulation execution but improves working with the output file. The type attribute stands for the name of the implementation as defined in the simulation file and id for the identifying number of the agent or object. For printing the property value pairs, the Slot element is used again here. Since agents also have an internal state, they may have several self belief properties. These are printed using the SelfBeliefPropertySlot element. To print the property names and their values, the reflection layer is also used here. This allows to get all properties the user defines in a simulation file although they are not known to the logger at compile time.

<SimulationState>
  <Objects>
    <Object name="..." type="..." id="...">
      <Slot property="..." value="..."/>
      ...
    </Object>
    ...
  </Objects>
  <Agents>
    <Agent name="..." type="..." id="...">
      <Slot property="..." value="..."/>
      ...
      <SelfBeliefSlot selfbeliefproperty="..." value="..."/>
      ...
    </Agent>
    ...
  </Agents>
</SimulationState>

4.7.3. Implementing an Easy-Plugging Logger Architecture

Another useful extension to the core functionalities of AOR-JSim marks the implementation of an architecture to easily plug in new logger implementations. The idea is to make it possible that a user can write an own logger implementation and use it with AOR-JSim without the need to recompile the complete program code. This is also necessary in cases where a user only has the program library but not the source code of AOR-JSim. Then the user would not yet even have the possibility to create own implementations of the logger interface, since she could not integrate this logger to make it available to the user interface. Thus, a mechanism was needed to enable using loggers that have not been known to the program at compile time. To sum up, the following is needed:

  • a logger interface

  • a place to plug in new logger classes

  • the possibility to choose the appropriate logger from the user interface

  • a mechanism to find and load available loggers

  • a way to set the chosen logger to the simulation main class

The first point in the list has already been introduced in Section 4.7.1, “Introducing an Interface to collect Simulation Data”. The interface AORJSimLog extends the basic logger interface by a method that enables setting the user interface main class to implement a feedback possibility to AOR-JSim. The user interface in turn has a method for receiving logger output that can then be displayed. Thus, implementing this interface is the first necessary step. The following code listing shows an extract from the XML logger implementation that is described in this section. For sending data back to the user interface it is necessary to implement the setGUI method. After this is done, generated text can be send to the main class by invoking the method appendLogText as shown in line 15. To successfully plug in the new logger implementation, it should be placed in the package aorsimstats. This folder is also the place to copy the compiled class file.

package aorsimstats;

import aorsimulation.agentsimulator.*;
import aorsimulation.baseclasses.*;
import aorsimulation.environmentsimulator.*;
import aorgeneration.gui.GUI;
...
public class XMLLog implements AORJSimLog {
...
  public void setGUI(GUI gui) {
    this.gui = gui;
  }
...
  private void printOutput(String out) {
    gui.appendLogText(out);
  }
...
}

After starting AOR-JSim, the actual process of finding, loading and using loggers starts. Figure 30, “Activity diagram of pluggable logger architecture.” shows an activity diagram with the complete process. It starts in (1) with the initialization of the user interface. Here, the folder aorsimstats is checked for available logger classes. The class names are taken from the found files and are shown in the user interface tool bar. At this point, the user can select the desired logger. After the start button was pressed, the program must now try to load and initialize the chosen logger class (2). Since logger classes cannot be known to the program at compile time, it is necessary to use a class loader to get an instance of the class. The class loader introduced in Section 4.7.2, “Creating an XML based Output File” is again used here. When the logger is successfully created, the user interface instance must be set (3). In step (4), the simulation main class gets created and the logger instance is assigned to this class (5). Then, the simulation gets started. While simulating step by step (6), the simulation main class invokes notify methods on the logger class (7). The logger can now process the given simulation data to create log text. Finally, the logger class sends the created log text to the user interface (8). The user interface will then append this text to the output panel.

Figure 30. Activity diagram of pluggable logger architecture.

Activity diagram of pluggable logger architecture.

4.8. Implementing a Simulation Control Center

In many cases it will be useful to have the possibility of pausing a simulation or running a simulation step by step. This may be for debugging purposes while developing a simulation file. In general, a step mode makes it easier tracing developing of values. Since simulations can possibly run a large number of cycles, it is also necessary to enable adjusting the number of steps. For instance if a simulation will run 10000 cycles, it might be better to run 100 steps than just one single step to check for intermediate results. As can be seen in the state machine depicted in Figure 31, “State diagram of simulation player functionalities.”, a complex implementation is necessary to enable all described functionalities.

Figure 31. State diagram of simulation player functionalities.

State diagram of simulation player functionalities.

The state diagram contains several variable names that are necessary to explain the diagram. The following will describe them for a better understanding.

currentTime

A variable that indicates the current time of the simulation.

stopTime

This variable is used to adjust a definite end point of a simulation. The is useful, since simulations can be non self-terminating.

timeCountDown

The amount of simulation time that will be simulated consecutively in step mode. This number can be adjusted by the user before clicking the step button. After every simulated cycle, this variable will be decremented by the size of one step. If it reaches zero, the simulation will pause.

cycleDuration

This indicates the size of a step in simulation time. This can be specified as parameter in an AORSML file.

time

The step time is the variable that a user passes while pressing the step button. The user adjusts this time value with the user interface. The simulator will then simulate this amount of time without pausing.

Before starting a simulation, the user can choose if she wants to run the simulation normal or in a step mode. After pressing the run button, the simulation is in the Running state. Now the simulation runs until one of the following occurs: there are no more future events to simulate, the current time is equal to a predefined stop time, the user presses the stop button or pauses the simulation. The first three change the state of the simulation from Running to End. It must be mentioned, that pressing the stop button doesn't ends a simulation immediately but finishes the current running simulation cycle first. If no value for the stop time is set, it is possible that a simulation might run for ever without pressing the stop button. This is due to the fact that one could define events that always result in new events. After ending the simulation, it is possible to press play or step again, but this leads to a new simulation run. After pressing the pause button, the state of the simulation changes to Pause. Like stopping the simulation, after pressing the pause button, the current cycle will first be finished before changing the state. As can be seen in the figure above, the Pause state offers different possibilities. Pressing the pause button now changes the state back to Running. While in Pause state, pressing the stop button ends the simulation here immediately. Finally, it is possible to leave the Pause state by pressing the step button.

The second possible mode running simulations is the step mode. This mode can be chosen either at simulation start or in Pause state. Before pressing the pause button, the user can choose the step time. This is a multiple of the step size. For instance, if one step has a "size" of 7 days, it is possible to chose a step time like 14, 21, 35 and so on. The simulator will now simulate on cycle. After this cycle, the step counter variable gets decremented by the step size. This will be repeated until the step counter reaches zero. Then the simulation will change it's state to Pause. While running in step mode, the simulation can also end before the step counter reaches zero. This happens if there are no more future events to simulate, the stop time is reached or the stop button gets pressed. Finally, the step mode can also be paused by pressing the pause button. This changes the simulation state to Pause and pressing the button again returns to the step mode.

5. Creating a Statistic Center for Live Evaluationof Simulations in AOR-JSim

To evaluate simulations, it is useful to analyze the results of a simulation with the help of graphical charts. The Repast project as described in [Repa06] already introduced graphical analysis possibilities for their Repast Simphony simulation toolkit. To enable such functionality for Agent-Object-Relationship Simulations, a challenge was to develop an architecture for creating live statistics for AOR-JSim. This includes displaying properties to choose for analysis, following property changes and creating chart images from property values. This requires an extra architecture to include into AOR-JSim that will be introduced in Section 5.1, “An Architecture for Collecting Values and Creating Charts”. After this, Section 5.2, “Creating Charts” shows how charts will be created. Finally, Section 5.3, “Extension of AOR-JSim Project Files for Statistic Settings Support” describes necessary extensions to AOR-JSim project files to save and restore settings of the statistic center.

5.1. An Architecture for Collecting Values and Creating Charts

For creating charts directly at simulation runtime, it is necessary to develop a complex architecture for collecting property values and graphical output. There are several questions that must be answered. First, which properties can be traced and how users can select these properties. Then, how to receive information when a value of a property changes and, how to display the progress of values with the help of charts. Finally, the question will also be how to integrate everything into the generator and simulator software environment. This section will introduce an architecture that solves all described problems.

To start, the first question that must be answered is what properties of an AOR simulation may be traceable. All entity types in AOR can have properties that define the state of the entity. This includes not only objects and agents but also events, actions, perceptions and messages. But, only objects and agents exist for the whole simulation time[40]. Events, actions, perceptions and messages are temporary entities, that only exist for a short time and stop existing after they occurred. Thus, only agent and object properties might be interesting for being traced in a simulation. So, the next questions is, how available properties are found and displayed to users of AOR-JSim. Properties are defined within AORSML simulation files. As mentioned, AOR-JSim processed these simulation files to create Java source code. Thus, when creating source code, the information about all defined entity types, including agent and object properties is available to AOR-JSim. To choose properties for tracing, there are two possibilities. One could consider to extend the XML language by adding an attribute to every property definition that marks the property as being traced. This approach has a large disadvantage. Properties are chosen static, changing the settings would always require new code generation. But, there is another possibility. When creating Java code from AORSML, the whole information included in the simulation description file is available through a set of Java objects. Thus, these objects can also be used to collect information on all agent or object properties to make them available for the selection via the user interface. Figure 32, “Choosing properties via the user interface of AOR-JSim.” is a screenshot detail of AOR-JSim showing how users can select properties for tracing. All properties of all agents and objects that are defined in a simulation file can be selected. For the sake of clarity, agent and object entities are displayed in separated tabs and every entity is displayed in the form (entity-id) entity-name [entity-type].

Figure 32. Choosing properties via the user interface of AOR-JSim. Agents and objects are displayed with an extra tab. Every tab contains the list of defined agent instances or object instances, respectively. To distinguish between different instances, the name and id of an instance are shown as well as the type of the entity. When selecting an entity, all defined properties are shown and can be selected.

Choosing properties via the user interface of AOR-JSim. Agents and objects are displayed with an extra tab. Every tab contains the list of defined agent instances or object instances, respectively. To distinguish between different instances, the name and id of an instance are shown as well as the type of the entity. When selecting an entity, all defined properties are shown and can be selected.

After getting all selectable properties displayed, the question is how to receive information about a specific property when a value changes in a running simulation. This includes several tasks. First, AOR-JSim must tell the simulation system what properties of which entities should be traced. Second, the simulation system must forward this information to the specific class instances of the agents or objects who own the properties. Third, while the simulation is running, the entities must send back information whenever a values changes. This all forms the actual architecture for collecting property values. Figure 33, “Architecture for collecting values and creating charts.” shows this architecture that will now be explained in detail. As mentioned before, package aorgeneration that includes the logic for code creation and execution on the one hand and the user interface classes on the other hand is separated from package aorsimulation that includes classes for the simulation process as well as classes for all basic simulation entity types. In fact, AOR-JSim can access all classes, but the simulation package is independent since it should be possible to run simulations without the generator software. Thus, there is no direct way for receiving feedback from a running simulation. To solve this problem, it is necessary to add feedback functionality to simulation classes. This can be done with event listeners. Such listeners listen to special events somewhere in a program and process them when they occur. This can be compared to interrupts on the hardware layer. In Java, event listeners are usually used in user interface programming. For instance, Java provides classes that display a button like the JButton class of the javax.swing package. Simply placing a button on a panel already displays the button. But a program must know when a user presses this button. Thus a programmer can use an action listener. The button class sends an action event to all action listeners that are plugged to it. Listeners in turn are usually interfaces. A programmer simply implements the specific interface and then adds this new listener to the class that creates events for the listener interface that was implemented. Such a listener architecture also seems appropriate for the given problem. As can be seen in Figure 33, “Architecture for collecting values and creating charts.” there is a special listener interface called StateChangeListener placed in package aorsimstats.event. This interface inherits from java.util.EventListener. This super interface has no own functionality, but it is necessary to inherit a listener interface from EventListener to identify the interface as event listener [SUN04]. The StateChangeListener interface has two important methods: registerProperty and stateChanged. The first method is used to register properties to this listener. Since an agent or object can have a lot of properties, only those who should be traced must be registered at the listener. Registering is done before simulation start after a user has chosen properties via the user interface as shown in Figure 32, “Choosing properties via the user interface of AOR-JSim.”. For every instance of an agent, internal agent and object, one listener will be created and all properties that should be traced are registered at the corresponding listener instance.

Figure 33. Architecture for collecting values and creating charts.

Architecture for collecting values and creating charts.

The second important method of the interface StateChangeListener - stateChanged - will then be used while the simulation is running for notifying the listener about a change of a value of a property that is registered at this listener. At this point, the next question is when and how to call this method of the listener from an agent or an object entity. Properties change when a rule processes state effects and there sets a new value of a field of an instance of some agent or object. For instance, if an agent has a property that stores the current money of his bank account, called accountBalance, simply setting a new value like accountBalance = 100 changes the state of the agent. But, at program level, the agent class does not notify that the value changes. Thus, it is necessary to create some new functionality when creating Java source code from AORSML simulation definitions. The solution is to create special set methods for all properties of all agents and objects that are defined in the simulation file. Within this set method it is now possible to add source code that will be executed in the case a new value will be set. For the example of the accountBalance property, the next listing shows the corresponding setAccountBalance method that would be created for this property. The name of every set method contains the name of the property in a way that the name of the set method for property property is setProperty. The second line in the listing below is the actual value assignment. The rest of the listing is code for creating a new StateChangeEvent and sending it to all listeners that are interested in receiving the new value. To enable adding an arbitrary amount o listeners, an EventListenerList from package javax.swing.event is used to store all registered listeners. This list will be iterated while for every listener a type check will be done. As can be seen in line 9, before creating a new event, it must also be checked if the property is registered at the listener. If this is true, a new StateChangeEvent gets created with the name of the property and the new value. Finally, the event is passed as argument of the stateChanged method to the listener.

public void setAccountBalance(int val) {
  accountBalance = val;
  Object [] listeners = listenerList.getListenerList();
  // Process the listeners last to first, notifying
  // those that are interested in this event
  for (int i = listeners.length-2; i>=0; i-=2) {
    if (listeners[i] == StateChangeListener.class) {
      StateChangeListener l = (StateChangeListener)listeners[i+1];
      if (l.propertyIsRegistered("accountBalance")) {
        StateChangeEvent e = new StateChangeEvent("accountBalance", ""+val);
        l.stateChanged(e);
      }
    }
  }
}

The connection between the user interface and the simulation system is done with the listener implementation StatsStateChangeListener that can be seen in Figure 33, “Architecture for collecting values and creating charts.”. This class holds an instance of the class of the user interface that draws the charts: StatsChartPanel. When the stateChanged method is called from an entity of the simulation system, the listener implementation forwards the information about the changed value to this class of the user interface by calling the setValue method. Now, the new value of the property can be used to update the graphical output.

As Figure 33, “Architecture for collecting values and creating charts.” also shows, class GUIStatsPanel can be connected to several instances of the two classes StatsChartPanel and StatsConfigTab. This enables to create several charts concurrently for one simulation example at one single simulation run. This is important, since it is often necessary to follow different properties in a simulation that should not be in the same chart. For instance, one chart compares the inventory of all Beer Game supply chain nodes over time and another chart compares the overall costs of these nodes. Class GUIStatsPanel controls this part of the architecture. It is responsible for creating the backend of the statistical output. Figure 34, “Main composition of Statistic Center User Interface” shows the basic structure of the user interface created by GUIStatsPanel. It is divided into three main parts. The first part is a panel at the upper left corner that shows all available agents and objects in a specific simulation plus their properties to choose. This part was already explained at the beginning of the section. See Figure 32, “Choosing properties via the user interface of AOR-JSim.” for a screenshot of this panel. The other two parts are used for configuring and displaying of different charts. On the left side, below the explained property panel, there is a tabbed panel that can include an arbitrary amount of panels for configuring chart output. Every tab contains one instance of class StatsConfigTab. Every instance controls a set of parameters of a chart, for instance the type of chart or the title. More details will be explained in Section 5.2, “Creating Charts”. As can be seen in Figure 34, “Main composition of Statistic Center User Interface”, below this tabbed panel there is a button that adds another chart. This includes also a new configuration panel. On the right side of the whole composition, there is the third part that is used to display frames that paint the actual charts. This is done with a class named StatsChartPanel. Every instance of a StatsChartPanel gets embedded into a JInternalFrame from the Java Swing library. Thus, as Figure 34, “Main composition of Statistic Center User Interface” shows, it is possible to display several charts concurrent on the screen. Every instance of class StatsChartPanel stands in connection to exactly one instance of class StatsConfigTab. This enables information exchange in case the user changes the configuration. These changes are transferred from one class to the other by calling special setter methods. This also increases the reusability of these classes, since it facilitates to use these classes for other software projects.

Figure 34. Main composition of Statistic Center User Interface

Main composition of Statistic Center User Interface

5.2. Creating Charts

After introducing an architecture to collect values and create charts, this section describes the creation of chart graphics in detail. The task is to draw charts of selected properties live at simulation runtime. A first question here is what charts to integrate in the statistics center. There are lot of different types of charts that are used to display value patterns or to illustrate the context between different values. Often used chart types are line charts that display value patterns, pie charts to show the percentage between single values of different entities or bar charts to compare single values quantitative. These types of charts fulfill most requirements, so these should be implemented. Every of these three chart types has special characteristics in creating the chart area as well as in displaying the values. For instance, as can be seen in Figure 35, “Screenshot showing different created Charts.”, a line chart requires drawing a coordinate system and a lot of different values of different properties. On the other side, a bar chart only shows one single value of every property compared to other properties. The next sections will explain the creation of every type in detail.

Figure 35. Screenshot showing different created Charts.

Screenshot showing different created Charts.

5.2.1. Line Charts

The creation of a line chart can be divided into two separate processes. First, it is necessary to draw some coordinate system with an x and a y axis. After this, the second step is to draw in the values and connect every two successive values by a line. For both processes it is required compute a mapping of real simulation values to screen coordinates. The very first step is therefore computing a conversion factor between screen coordinates and simulation specific values. The parameter to use for converting domain values xwidth depends on the width of the chart in pixels Cwidth [41], the maximal value displayed on the x axis xmax and the minimal value displayed xmin. The two values that define the visible area of the x axis can be specified by the user per chart configuration parameters. The x axis is used in chart creation for the simulation time. Thus, the minimal value xmin cannot be less than 0, but any positive integer. These two values can be used to draw a clipping of the whole chart. The next equation shows how the xwidth parameter will be computed:

After this, the conversion factor for the y axis yheight must be computed. This parameter logically depends on the height of the chart in pixels Cheight as well as the minimal and maximal displayed values on the y axis: ymin and ymax. As described for the x axis creation, these two values can also be used for draw clippings of the whole chart. In opposite to the x axis, the parameter ymin here can also be less than 0. The following equation shows how the conversion parameter for values on the y axis gets computed:

After this, it is necessary to determine the origin of the coordinate system. This must be done since setting values for xmin and ymin, moves the origin of the coordinate system on the screen. The x value of the coordinate system origin originx depends on the x value of the chart screen coordinate Cx, the minimal x value xmin and the conversion parameter xwidth. The y coordinate of the origin of the coordinate system originx depends on the product of the minimum y value ymin and the y conversion parameter yheight and the sum of the chart y coordinate Cy and the height of the chart Cheight. The next two equations are used for these computations:

With these parameters, it is now possible to draw the coordinate axes and the grid. After this is done, the values can be drawn into the coordinate system. All properties that should be drawn into the chart are stored in a vector. Every vector of every property in turn has two vectors. The first contains all x values that specify the simulation time when a new value of a property occurred. The second vector contains the corresponding property values. This means, a property element consists of a set of (ti, vi) tuples with t as time value and v as property value. As mentioned, the simulation time will be displayed on the x axis and property values on the y axis. Thus, for converting a time value, the introduced parameter that belongs to the x axis must be used. For computing the x coordinate x within the drawing area of the chart, the current time value ti must be multiplied by the parameter that specifies the conversion from x values to pixels xwidth. After this, it is necessary to add the originx parameter, since the origin of the coordinate system can be moved. The next equation shows the described conversion of a time value to the x value of a screen coordinate:

Finally, it is necessary to convert every property value to the corresponding y value of a screen coordinate. From the base point, the y coordinate of the origin of the coordinate system originy, the product of the current property value vi and the conversion parameter yheight will be subtracted. The following equation shows this:

To create a real line chart it is important to connect all values of a property by lines. This is done by drawing a line from point (ti-1, vi-1) to point (ti, vi). To distinguish between the curves of different properties, the user can specify the color of every line, the stroke and finally a symbol that will be drawn at every value coordinate. Figure 36, “Example line chart created with AOR-JSim.” shows an example of a line chart created with AOR-JSim. As can be seen, it is also possible to draw a chart title, a description for the x and y axis and a legend.

Figure 36. Example line chart created with AOR-JSim.

Example line chart created with AOR-JSim.

5.2.2. Pie Charts

Another prominent chart type are pie charts. They do not show real values, but they are best in showing percentaged ratios of different values. For instance, pie charts are used to display voting results. But showing the ratio of different values of a simulation can also be useful, thus, they have been integrated in the statistic center. In contrast to line charts, pie charts have completely different characteristics and parameters when drawing them. For instance, they can only show one single value of every property. And they do not directly show any exact value, only a percentaged value in comparison with values of other properties. For every value, one segment of the complete circle must be drawn. This size of every segment depends not only on the value of the property but also on the sum of all values that should be drawn into the chart. Therefore, it is first necessary to determine the sum of all values that will be compared. Since every property usually has several values, the questions is to use the sum of all values of one property or only the last value. The decision is to take only the last known value. When a user needs the sum of all values, she simply needs to define a property of an agent or object that sums up all values. So, the sum S of all values will be computed. Since properties are managed by time-value tuples of the form (ti, vi), retrieving a value at a specific time can be described as function f(ti) = vi. Computing the sum can finally be done with the following equation:

Next step when drawing a pie chart is to compute the angle of every segment of the circle. This angle α is the quotient of the last value of every property v and the sum of all these values S multiplied by 360 as the next equation shows:

After computing all angles, it is possible to create instances of Arc2D.Double from package java.awt.geom, that can be drawn using a Graphics2D object from package java.awt. As for line charts, also pie charts can have a title that can be specified with the user interface. Figure 37, “Example pie chart created with AOR-JSim.” shows an example of a pie chart created with AOR-JSim.

Figure 37. Example pie chart created with AOR-JSim.

Example pie chart created with AOR-JSim.

5.2.2.1. 3D Pie Charts

Three dimensional pie charts are also often used. They have the same meaning as normal pie charts, but they simply look more "fancy". The first part of the pie chart creation is completely the same as for normal pie charts. But, they differ in the way the chart gets painted. There are two reasons for this. First, the pie is not a circle but an ellipse. Second, there is some three dimensional effect that must somehow be created. Creating an ellipse instead of a circle is pretty simply using the mentioned Arc2D.Double class. In Java, this arc object gets defined with the width and height as well as the x and y coordinate of the upper left corner of the boundary rectangle. When creating a circle, width and height will be equal but they will differ for an ellipse. The more complicated part is the creation of the 3d effect. Figure 38, “Creating a 3d pie chart: overlapping two ellipses brings the 3d effect.” shows a first solution. A second ellipse will be drawn with a small vertical shift. This ellipse has darker colors as can be seen in the image. The dotted line simply shows the border of the underlying ellipse. Now, there is some easy 3d effect.

Figure 38. Creating a 3d pie chart: overlapping two ellipses brings the 3d effect.

Creating a 3d pie chart: overlapping two ellipses brings the 3d effect.

But, simply drawing two ellipses as shown in Figure 38, “Creating a 3d pie chart: overlapping two ellipses brings the 3d effect.” does not completely solve the problem. Below, Figure 39, “Problems when simply drawing two ellipses: pie pieces are not perfect.” shows the following problem. As can be seen in the left and right version shown in this figure, there is an example piece drawn into the pie. Both parts of the piece, the upper one and the lower one are equal except that the lower one is a bit darker to create the three dimensional effect. The left image shows what happens when both pieces - the lower and upper - are simply drawn into the pie. The image on the right side of the figure shows a correct painted area. The dashed lines in both images are only for showing the area of the piece that needs to be drawn. The red lines are used for explaining the problem and its solution.

Figure 39. Problems when simply drawing two ellipses: pie pieces are not perfect.

Problems when simply drawing two ellipses: pie pieces are not perfect.

As can be seen in the left image, the real lateral area of the cylinder that is created with the two ellipses is not correct filled with the darker color of the piece. Numbers (1) and (2) show the parts of the arc that are incorrectly filled. While the area at (1) should be painted with the dark color of the piece, the area at (2) should not get the color of this piece of the pie. The two red lines delimit the area of the lateral area that must be painted in the darker color as the right version in the figure shows. To solve the described problem, it is necessary to draw additional areas. The area marked with (1) can be filled by adding a rectangle that includes the coordinates of points upmid and lowmid and the start and end point of the red line at area (1). The first two coordinates mark the middle points of the upper and lower ellipse, the other two coordinates mark the intersection of the starting angle from the upper and lower arc with the respective ellipses. To get the area in (2) filled correctly, the same rectangle from the next piece of the pie must be drawn. Logically, if the ending angle of the arc shown in Figure 39, “Problems when simply drawing two ellipses: pie pieces are not perfect.” would lie in the third quadrant of the coordinate system with an origin in the middle of one of the ellipses, the rectangle to draw must be in the color of the current arc. Finally, when everything is drawn correctly the three dimensional pie chart would look like the example shown in Figure 40, “Example of a created 3d pie chart.”.

Figure 40. Example of a created 3d pie chart.

Example of a created 3d pie chart.

5.2.3. Bar Charts

Finally, the task is to include bar charts into the statistic center. Like the pie charts that can be created with AOR-JSim, also bar charts will only use the last value of every measured property. Bar charts usually only use one value axis, here the y axis. The x axis has no scale. Bars are drawn vertical, this means, the height of every bar specifies the value of the measured property. Therefore, it is only necessary to determine all parameters used for creating the y axis. Since, it will show property values as line charts do, the same computations can be used again. See Section 5.2.1, “Line Charts” for all needed equations to determine yheight and originy. Before drawing the bars, the width of every bar barwidthmust be determined. Since there should be a gap between every bar and the width as well as the gap should depend on the current width of the chart, it is a good solution to divide the width of the chart Cwidth by the number of measured properties #p plus 1. The resulting free space in the chart is exactly as wide as the width of one bar. The gap between every two bars gap also depends on the current width of the chart. Since the gap between every two bars should be equal[42], the free space must be divided by the number of measured properties. The following two equations show how the width of every bar and the gap will be determined:

Finally, the height of every bar must be computed. The height is the value of the property converted to screen pixels. As mentioned before, only the last value of every property will be used. Properties have a set of tuples of the form (ti, vi), with ti as time and vi as the value at this time. Thus, retrieving a value can be done with the following function:

This function can now be used to retrieve the last measured value by using tmax as argument of the function. By multiplying the result with the conversion factor yheight, the height in pixels of the bar gets computed. The next equation shows this computation of the bar height:

After all these parameters are computed, all bars can be drawn into the chart. See Figure 41, “Example bar chart created with AOR-JSim” for an example bar chart created with AOR-JSim.

Figure 41. Example bar chart created with AOR-JSim

Example bar chart created with AOR-JSim

5.3. Extension of AOR-JSim Project Files for Statistic Settings Support

To complete the integration of the statistic center, it necessary to extend the project file creation with all needed settings to restore a current statistic center configuration. This is very important, since there are plenty of settings that needed to be repeated when loading a project without statistic configurations. To restore the last configuration of the statistic center, the following settings must be saved:

  • number of agents and objects

    • name, type and id of every agent and object

  • property information about every agent and object

  • number of opened chart windows

  • configuration of every chart

    • type of chart

    • title of chart

    • x axis configuration including title, min, max and graduation

    • y axis configuration including title, min, max and graduation

    • visibility of grid

    • visibility and configuration of legend

  • registered properties for every chart

  • configuration of every property

    • symbol for line charts

    • line stroke for line charts

    • color

Beyond these settings, there are several extra settings that can be stored in a project file but are not compulsory. These next settings will be stored in addition to the described mandatory settings above:

  • size of every chart

  • position on the screen of every chart

  • position of movable divider between the configuration panel and the chart window

All this data described above will be stored when a user saves the current project. The basic process of creating project files as well as their structure was already explained in Section 4.6, “Creating Project Files”. Therefore, the additional information can simply be collected and attached to the current project file information. The following listing shows some sample project file lines concerning the configuration of one chart. For instance, the key aorsimstats.chart.0.main contains the current chart type (0), the chart title (Costs Comparison) and two boolean values for showing the grid lines and the legend.

<entry key="aorsimstats.chart.0.main">0/Costs Comparison/true/true</entry>
<entry key="aorsimstats.chart.0.bounds">6/3/411/355</entry>
<entry key="aorsimstats.chart.0.xaxis">Time (days)/0/70/7</entry>
<entry key="aorsimstats.chart.0.yaxis">Costs (in €)/0/150/10</entry>
<entry key="aorsimstats.chart.0.legend">(%I) %N</entry>

The next listing is an example for the settings of the first property that was registered to the first chart. It contains the type (SupplyChainNode), id (1) and name (Retailer) of the owner entity of this property and the name of the property (costs). In this particular case, the entity is the first agent in the supply chain of the Beer Game as described in Section 3.5, “Modeling a Beer Game Simulation”. In addition to this, this line also contains configuration parameters for charts drawing like the line stroke and symbol for line charts and the color.

<entry key="aorsimstats.chart.0.property.0">
  SupplyChainNode/1/Retailer/costs//true/-65536/3/0
</entry>

There are a lot more settings as described above, but the shown lines will be enough for giving an insight into statistics project settings. By adding the information described in this section, it is possible to store the complete statistic center configuration to project files. This enormously facilitates the work with AOR-JSim.

6. Multithreading and Distributed Simulation

To extend agent based simulation as described, a task was to investigate the possibilities of multithreading and distributed simulation. These are two different approaches, that share some characteristics. While agent based simulation as described in this work usually runs step by step in a fixed order, the multithreading and the distributed approach allow concurrent agent simulation. This means, several agents can be simulated at the same time. The simulation system calls every agent at the beginning of a new simulation step and waits for the results. This may be interesting for two cases. First, it allows user interaction with the simulation system. Every agent may be controlled by a real person, for instance for a game simulation. The Beer Game for instance can also be played by human players. Some supply chain nodes could be controlled by a normal agent simulator and some by user interaction. A second interesting possibility for concurrent agent simulation is in the case that there are complex computations that an agent has to make. A distributed simulation as well as a multithreaded simulation on a multi-processor computer can speed up such simulation scenarios.

The following sections investigate the possibilities and also the problems of multithreaded or distributed AOR simulations. To begin, Section 6.1, “Introducing a Multithreaded AOR-JSim Version” introduces a multithreaded version of AOR-JSim. After this, Section 6.2, “Distributed AOR Simulation” investigates on distributed AOR simulation.

6.1. Introducing a Multithreaded AOR-JSim Version

This section introduces a multithreaded version of the simulator software. Multithreading in this context means, that every agent simulator in a simulation runs in a separate thread. Usually, only the simulation system main class runs as a thread but not the environment simulator and not the agent simulators. The simulation system controls the simulation execution by first invoking the simulation step method of the environment simulator and then by invoking every simulation step of every agent simulator one after the other. While calling an agent simulator, the simulation system blocks and waits for the result of the specific agent simulator. This blocking is usually not problematic, simple simulations like the Beer Game have no complex computations. In a test, one agent simulator step in the Beer Game simulation with AOR-JSim on a standard PC took between several hundred microseconds and one millisecond[43] with several other applications running at the same time. But, when creating scientific simulation scenarios where agents have to perform complex computations, it might be interesting to simulate several or all agents concurrently. Of course, simply putting every agent simulator in a own thread does not speed up a simulation. On a single processor PC, this can even slow the whole simulation down. Every context switching between two threads takes some time. But, on a multiprocessor system, multithreading can speed up a programs processing.

When executing every agent simulator as a separate thread, there is one problem that occurs when creating XML based simulation output as described in Section 4.7, “Creating Structured Simulation Output”. If all agents are simulated concurrently, they might send information about their current simulation step at the same time to the logger class. Thus, a correct order cannot be ensured any longer. This can then result in non well formed XML output. To solve this problem, there are two possibilities. The easiest way is to simply don't print any information about every agent simulator step. Of course, this does not affect printing the state information about every agent after each simulation step, only the information what happens during a step. A second possibility is to rebuild the simulation output logging process. Every logger method that is used for notification of some agent activity needs to be extended with another parameter that identifies the agent that notifies the logger. The logger then needs to collect all information about each agents step. When an agent finishes its current simulation step, the logger can create the complete agent simulator step output about this specific agent and add it to the complete output file. To conclude, the first solution is suitable in the case that only the state of the agent after every simulation step is interesting and the second solution if the complete information is needed.

An interesting possibility of a multithreaded simulation execution is interactive simulation. This means, agents can be controlled by human interaction. Section 6.1.1, “Interactive Simulation” describes an interaction approach for Agent-Object-Relationship Simulation via AOR-JSim.

6.1.1. Interactive Simulation

The multithreading approach described above, opens up the possibility to enable user interaction in a running simulation. A user can take control over an agent simulator and may influence the results of the simulation by this. Sure, a user controlled agent is also possible without agent simulators running as threads. This would mean, the simulation system will block until a user finishes the current simulation step. If several agents are controlled by users, every user must wait until all agents before her own agent finished their simulation step. For instance, if there are four agents, numbered 1 to 4, with 1 as first agent, agent 3 can only act if agents 1 and 2 have finished their current simulation round. This may be sufficient for a simulation like a card game, where every player must do her step in always the same order. But interactive simulation with agents running as thread makes simulations possible, where the simulation runs continuously no matter if the human controlled agent finishes its current simulation step or not. This means, at the start of a new simulation step, the simulation system first calls the environment simulator, then it sends new events to every agent and waits some time for receiving results from every agent. When this time has elapsed, the simulation system ends the current simulation step. If an agent has not finished its current simulation step before the time has elapsed, it will simply not send any result back to the simulation system. This makes it possible to develop for instance some kind of role player game where the human controlled agent acts asynchronously with the simulation system. The simulation still runs in well defined steps, but an agent doesn't coercively need to send in a result for every round. Therefore, it is necessary that every agent, or at least every human controlled agent must run in a separate thread.

To allow user interactions with the simulation system, it is necessary to create a user interface. Since every agent is controlled by one agent simulator, the best way is to extend the normal agent simulator for receiving user inputs. To do this, a questions is, what should a user be able to do. Theoretically, it is possible that a user can do everything with an agent, this means, the user can choose any resulting message, action or event when reacting on incoming events. Another idea is, that a user can only choose different property values of resulting messages, actions or events. Sometimes, a property of an action or message depends on other properties. For instance, in the Beer Game, the amount of beer to ship depends on the amount of received orders and the current inventory. When a user should be able to control the amount of beer to ship, it would be necessary to insert some restrictions. To simplify matters, it should be made possible to specify properties in a simulation description file to that a user can choose the value. The next listing shows a modified version of the beer order message from the beer game. The quantity property of the message has a new attribute with name userInput. Every property that has this attribute and the value of the property is true should be made available for user input.

<MessageType name="Order" receiver="SupplyChainNode" sender="SupplyChainNode">
  <Property name="quantity" type="int" userInput="true"/>
</MessageType>

While the simulation is running, the agent simulator receives a set of new events and can check what rules apply to what event. Every rule can result in several other events, messages or actions. In the following, resulting events will be short for all resulting entities including actions and messages and resulting internal events. Every resulting event can have an arbitrary amount of properties. Each of these properties is simply a field of a Java class. At this point, a question is how to know what property can be set by the user, since the field of the class is only a variable with a name and type. The simulation file with the information shown in the listing above is not available at this point. But, in Java there is a possibility to add more information to a field, a type, a method and much more: annotations. Annotations can simply mark something of a class, but can also contain additional information. In this case, an annotation will be used to flag a field as property thats value can be set by the user. The next listing shows a part of the new generated Java code for message Order. As can be seen, the property quantity is flagged with the annotation UserInput. This annotation is a new created annotation type and located in the package aorsimulation.util that is used for helper classes or special tools. At runtime it is now possible to check whether a property is flagged with this annotation or not.

public class Order extends Message {

  @UserInput
  public int quantity;
...
}

In a next step, the actual user interface can be created. As mentioned above, the agent simulator will be extended by graphical elements to display current events, rules for these events and resulting events of rules. The creation of the user interface will only be described in a few words. Figure 42, “Graphical user interface for user controlled agent simulator.” shows the user interface for controlling an agent. The window title bar (1) displays the name, id and type of the agent. Below (2) is a table with properties of the agent and their current value. To receive updates in the case a value changes, an implementation of the StateChangeListener interface that is introduced in Section 5.1, “An Architecture for Collecting Values and Creating Charts” is registered on the agent. The next part (3) shows all current events for this agent with their properties. Within this panel, all rules that apply to the currently selected event are shown (4). For every selected rule, another panel (5) shows the resulting events. The panel below has two tables displaying all fixed values (6) and all editable values (7). Below these tables, there is a button for simulating the event. If invoked, the usual event simulation process will be started. Finally, at the bottom of the window, the remaining time gets displayed and there is a button to send in current results (8). All the shown information can be retrieved on the one hand directly from the received events and their rules or on the other hand by using reflection. If the time for a simulation step has elapsed and the user has not send in the results, this can also be made in the next simulation step. Since the agent simulator runs in a separate thread, an agent can also miss a simulation step or several steps. After the time has elapsed, the next step will start and the agent will receive new events from the simulation system for the new step. These are then added to the list of not processed events.

Figure 42. Graphical user interface for user controlled agent simulator.

Graphical user interface for user controlled agent simulator.

Finally, a question is how to mark an agent as user controlled. There are also several possible solutions. On the one side, it can be possible to show all available agents via the user interface of AOR-JSim to select agents that should be user controlled. A second possible way is to add such information to the simulation file. The second solution seems better, since it will also work if the simulation will not be executed with the simulator. Thus, this solution is chosen. The next listing shows the element definition of the initial state of an agent from the Beer Game. The AgentInstance element has a new optional attribute called interactiveMode. If this attribute is set true, the agent can be controlled by a user. This also means, that it is possible to mark several agents as user controlled. For every agent instance that has a true value for this attribute, a graphical user interface as shown in Figure 42, “Graphical user interface for user controlled agent simulator.” will be created for agent control.

<AgentInstance instanceOf="SupplyChainNode" name="Distributor" id="3" 
               interactiveMode="true">
</AgentInstance>

6.2. Distributed AOR Simulation

The next step in the extension of normal Agent-Object-Relationship Simulations is a distributed simulation approach. Simulation distribution means that parts of the whole simulation are running in different environments or on different computers. There are several reasons why it can be good to distribute a simulation. One reason may be to use the resources of multiple computers: e.g., memory or CPU speed. Different computations can be split up to several smaller units and every unit will be computed on another PC. A prominent example for distributed computing is the SETI@home project [SETI01]. SETI@home is not a distributed simulation system but uses distribution as means for splitting up different tasks to speed up the whole computation process. The SPADES simulation system as introduced in [RLY03], is a distributed agent simulation system that uses distribution for time management of simulated agents. It is used for artificial intelligence research. Similar to AOR, an agent in the SPADES system receives events and reacts to them. Every agent runs on an own computer and communicates via a communication server with the simulation engine. The communication server also manages the so called thinking time of the agent. This seems to be the main reason for the distributed approach of SPADES. Another reason to distribute a simulation is to let people anywhere in the world take control over an agent of a specific simulation. An example simulation is a game where every player is an agent in the simulation. The Beer Game described in this work is also a possible candidate for distributed simulation. Every supply chain node can then be controlled by a user. The user interface can be an application that can connect to a simulation server or also a web application.

The results of the multithreaded simulation described before can hereby be used as starting point to investigate on distributed AOR simulation. In a distributed simulation, it doesn't makes sense to keep a special order of all agents that take part in a simulation. A fixed order would mean that an agent needs to wait until all agents that are in the line before itself, finished their current simulation step. Imagine a distribution approach where every agent runs on an arbitrary machine somewhere in the world connected via the Internet. Furthermore, suppose a simulation step takes 24 hours and there are several hundreds of agents and the users who control them are everywhere in the world. Every user now needs to check its agent simulator application if all agents in the line before have already made their step. This would make it very hard to participate in such a simulation. Thus, it is better, it does not matter when an agent sends a result during a running simulation step and, also, when an agent does not send a result at all. Therefore, there are several parallels between interactive multithreaded AOR simulation as described before and distributed AOR simulation.

This section is divided into two sub sections. First, Section 6.2.1, “Distributing the Simulation” investigates on the question how to distribute simulation entities and generated simulation code. After this, Section 6.2.2, “Communication Between Distributed Entities” deals with communication issues in a distributed simulation.

6.2.1. Distributing the Simulation

When creating a distributed AOR simulation, there are two important questions concerning the distribution process. The first question is what parts of the simulation can be distributed. In AOR, the simulation system controls the whole simulation process including the environment simulator and all agent simulators. Every agent simulator in turn in responsible for simulating exactly one agent. The simulation system itself only manages the transfer of resulting events from the environment simulator to all agent simulators and the other way round. In addition to this, the simulation system controls the simulation time and is able to create new agent simulators or to remove them[44]. Thus, the simulation system can be seen as some kind of simulation server. The environment simulator as well as all agent simulators may run on different computers or at least in different runtime environments[45]. Since the environment simulator doesn't represents an active entity but controls all objects and external agent states, it should not be controlled by a user. Therefore, only agent simulators may be distributed from the simulation system. Section 6.2.1.1, “Distribution of Agent Simulators” introduces a possibility for distributing agents.

A second problem concerning distribution is about distributing the generated Java code. As described in this work, AOR Simulations are written in an XML based description language that first must be transformed to executable Java code. An agent simulator can work with any generated AOR simulation. But all generated class files must be available at runtime. Section 6.2.1.2, “Distribution of Generated Simulation Code” deals with the problem of distributing generated simulation files.

6.2.1.1. Distribution of Agent Simulators

Distribution of a software means that several components run on different computers or at least in different environments or as different processes on the same computer. As explained, for the AOR Simulation System, the agent simulators should be extended to run them in a different environment. As for the multithreaded version, it must be possible that an agent simulator that is not user controlled should run as normal agent simulator. This requires an architecture where an agent simulator can run in the same environment or remote. Figure 43, “An architecture for agent simulator distribution.” shows a possible architecture for agent simulator distribution. The dotted line represents a possible boundary between two computers or two runtime environments. In this architecture, the simulation system communicates with a set of agent simulator proxies. The environment simulator runs in the same environment. The agent simulator proxy receives new events for its agent and returns step results back to the simulation system.

Figure 43. An architecture for agent simulator distribution.

An architecture for agent simulator distribution.

In the view of the simulation system, it still performs local communication with all agent simulators. The distribution is hidden to the system. This has the advantage, that the simulation system version can be the same as the multithreading version, except that a set of AgentSimulatorProxy instances is used instead of instances of class AgentSimulator. The proxy is able to connect to a remote agent simulator or to create a local instance if necessary. The inter-process communication between the proxy and the actual agent simulator can easily be realised via Java sockets. The agent simulator simply listens to incoming communication and starts working if new events arrive. After sending new events, the proxy will wait until receiving an answer. When the agent simulator has finished the current step, it sends back the results to the proxy. This is an example of a simple architecture. There are other possible solutions, but this example will be enough here.

As the agent simulator should be user controlled, the user interface version that was introduced in Section 6.1.1, “Interactive Simulation” can be used as base for the remote agent simulator. It must only be extended with some network functionality for sending and receiving data.

6.2.1.2. Distribution of Generated Simulation Code

One problem for a distributed simulation is the distribution of the generated simulation code. For every simulation specified in AORSML, a set of Java classes gets generated that can be executed. This set of classes must also be available at all remote agent simulators. Thus, before starting a simulation it is necessary to distribute these classes. Two possibilities will be described here. One possible solution is to distribute the generated simulation classes by hand to every remote agent simulator. This means, after generating and compiling simulation code, these class files may be send to every agent simulator that wants to participate in the simulation. This can be realised in any way that data can be put on another computer. This approach requires no extra code but is not very practicable.

Another approach is that simulation code will be transferred automatically when starting a specific simulation. The proxy of the agent simulator may send the needed files over the same connection as for all other communication issues. This can also be initiated by the agent simulator itself. A user may start an agent simulator and may then choose one simulation from a list of available simulations. Then, before simulation start, the agent simulator will request the needed class files. No matter what direction is chosen, this approach seems to be better than distributing class files by hand. But, of course this requires new functionality that needs to be implemented.

6.2.2. Communication Between Distributed Entities

In a distributed system, remote entities cannot communicate by simple method invocation. There is no common address space to access objects or data. Therefore, it is necessary to use other mechanisms to exchange data or to invoke remote methods. As mentioned before, the communication between the agent simulator and it's proxy should use sockets to exchange data. This is a simply way for sending and receiving data but doesn't makes it possible to directly invoke methods. Other techniques like Java RMI (Remote-Method-Invocation), hide the effort that is behind remote communication. For the user, it nearly seems like normal Java programming including normal method invocation. On the other side, an own solution may be good to allow proxies to communicate with agent simulators written in different languages[46]. A stream based socket communication allows to use agent simulators of any programming language. In this case, it is necessary to use a language for sending data that every entity can read and, of course, write. The next sub section, Section 6.2.2.1, “Simulation Data Exchange” investigates on a possible simulation data exchange language.

6.2.2.1. Simulation Data Exchange

In an AOR simulation, the simulation system sends new events from the environment simulator to every agent at the beginning of each agent simulation step. After simulating all current events, all agent simulators return a set of resulting actions and messages to the simulation system. In the local version of the simulator, instances of event, action and message objects are send between the entities. In the distributed version it is not possible to simply send these objects. They either must be serialized for sending or another solution must be found. All generated simulation files are in principle only mappings of elements of the simulation description language to Java code. When creating a simulation file, the developer needs to specify initial state elements for all entities that are needed at simulation start. This includes agents and objects but also events. An initial state definition is the state of an entity at simulation time 0. The same AORSML element can also be used to describe the state of an entity at any other time in the simulation. Therefore, the set of new events that an agent receives at the start of a simulation step and the result of this step can also be transferred into an XML file. The next listing shows an example result file from an agent. In this example, a supply chain node agent from the Beer Game ships beer to another agent and sends a new order message to the next agent in the chain.

<AgentStepResult>
  <EventInstance stereotype="ActionEvent" instanceOf="ShipBeer" actorID="2">
    <Slot property="quantity" value="7"/>
  </EventInstance>
  <MessageInstance instanceOf="Order" senderID="2" receiverID="3">
    <Slot property="duration" value="6"/>
    <Slot property="reliability" value="1"/>
    <Slot property="quantity" value="10"/>
  </MessageInstance>
</AgentStepResult>

To send such XML files from the agent simulator proxy to a remote agent simulator and back, they can easily be put onto the network stream as a string. Another possible way for sending the data is to put it into a SOAP message. SOAP is a protocol for exchanging data between different systems. The body of a SOAP message can contain any kind of XML. This protocol can also be used for remote procedure calls. Both described solutions have the advantage that the communication is independent from any programming language. A remote agent simulator can be written in any language, it only needs to be able to send and receive network communication and to read and write XML data.

7. Conclusion and Outlook

This thesis has introduced a Java simulation system for Agent-Object-Relationship Simulation. This simulation system consists of three main components: a library for generating Java code from simulation description files, a set of basic classes for executing AOR simulations and a user interface. It is based on a simulation system for agent-based and object-based simulation. The task was to enable Agent-Object-Relationship Simulation on the basis of this system.

The first part was the modification of the source code generation from agent-based to AOR simulation. This part included the development of an XML based simulation language for AOR simulation from the given language for agent-based simulation. The new XML language not only uses other element names, it is also much better structured. Furthermore, the language uses an XML Schema for validation. With the help of a Schema, a lot of possible sources for errors can be eliminated. The whole structure is also defined by this, what makes it easier to learn the language. To develop this language, it was necessary to create a simulation example for Agent-Object-Relationship Simulation. The used example, the Beer Game management supply chain, is an ideal example for creating an AOR simulation. In the basic version, it already uses most features of AOR simulations. While working on this simulation example, there have also been points where the limits of the current version of the language were reached. These limits have led to a lot of useful extensions of the language that are presented in this thesis. These extensions considerably enhance the possibilities of the language. For instance, it is now possible to create sets of agents or objects what is necessary if large a large number of similar agents or objects are needed in a particular simulation. Furthermore, new agents and objects can be created - or existing removed - in a running simulation. This can be important for several purposes. The current version of the language makes it now possible to create extensive Agent-Object-Relationship simulations. There is one more feature described in the principles of AOR Modeling that is currently not supported by the description language: the construct of institutional agents. Institutional agents consist of several other internal agents. The behavior of the whole institutional agent is therefore the sum of the behavior of all internal agents of it. It requires new language constructs but also larger modifications in the execution of a simulation model. This extension maybe an interesting task for some future work.

Parallel to the development of the language, the Java source code generation got changed from the given version to classes for AOR Simulation. This process also got optimized. For instance, functionality that was similar for different simulation classes was put into one single class that all other use. Furthermore, the modified generated source code includes new programming features like generic data structures. This generates safer source code, since when using generic data structures it is no longer necessary to do some type casts when trying to retrieve objects from a list or something like this. Therefore, the new code generation process not only creates classes usable for AOR simulations but also creates improved source code. In fact, the source code generation creates good and of course correct source code. In a future version, it may be good to think about using XSLT for transforming the XML simulation input files to Java code. Changes in the simulation language currently require re-implementations of parts of the software. This includes also a new compilation of the system. Thus, the effort in changing something in the simulation description language and adapting this in the source code generation is high. When using XSLT for the transformation from XML to Java, only changes in the XSLT stylesheets are necessary. No new compilation must be done. This is also good in the case a developer without programming knowledge wants to change something. Another idea for a future extension is to use the current library to generate source code in other languages, may be JavaScript code for some web-based simulation execution. To do this, a lot of code from the current version can be reused.

The next task described in this thesis was the creation of an improved user interface. Originally, the idea was to simply extend the existing software system to enable AOR simulations. But, very early it became clear that the existing software that was created to demonstrate the code generation and execution process, has only some basic functionalities and also a lot of faulty or inappropriate implemented parts. Especially the graphical user interface had only some small functionalities and some of them also produced errors. Thus, the whole user interface was revised and a lot of parts got re-implemented. The new graphical user interface only has some optical parallels to the original GUI, but the internal structure was completely changed. The architecture is much more object-oriented. The creation of the GUI is now divided into several independent modules and processes. It is now possible to change or extend parts of the GUI much easier and faster. Plus, parts of the GUI can also be used in other programs with only small modifications. The possibility to use project files makes simulation development and evaluation of simulation results easier. The software saves the whole current configuration, including information about the simulation generation process. Thus, a simulation developer can start working on a simulation, save the current work and continue at some other point in time. Furthermore, the integration of a program help to speed up the entrance to this software. Another important improvement to the simulation system is the simulation control center. This enables to pause or stop simulations as well as to run simulations stepwise. The user interface as created within this work is a much better tool for simulation developers. There are only less possibilities to enhance the software from the current point of view. One possible improvement may be a better tree view for the display of simulation input files. The current view already simplifies the overview on the simulation description code, but it is not possible to change the code directly with the help of the tree. When wanting to change something in the file, it is necessary to do this directly in the editor view of the XML file.

An important new feature for running AOR simulations with the simulator software is the creation of an XML based simulation log. The log file has a well defined structure based on an XML Schema and stores information about every detail of a simulation including the state of every agent and object after every simulation step. An XML based log simplifies extensive simulation post-evaluation.

A large part of this work was to find a way for creating live statistics during simulation execution. As explained in this thesis, an architecture was developed that makes it possible to choose simulation properties for statistical evaluation, receive events when the state changes and to display everything at simulation runtime. This architecture is now completely integrated into the simulation generation software and enables the generation of several charts for a simulation. Four different chart types are available that are commonly used for displaying charts for all kinds of statistical contexts: line charts, pie charts, three dimensional pie charts and bar charts. Furthermore, a wide range of modifications to a basic chart drawing are possible. Developers can adjust axis graduations, choose colors, line styles, add titles or maybe show or hide a legend. Thus, it is possible to create professional charts with the software.

The last part of this thesis was to investigate about multithreading and distributed simulation. An interactive simulator version was created to show the possibilities of multithreaded simulation execution. In this version, all agent simulators run in a separate thread, thus no sequence of agent simulator processing within one simulation step is important. Therefore, it is also possible that a user controls one agent or several agents. The necessary extensions to the simulation description language and the simulator software have been explained in this thesis. Finally, the possibilities of creating a distributed version of the simulator have been discussed. A distributed simulator architecture was introduced and a possible language for the communication between the distributed parts of the simulation system.

To completely conclude, it can be stated that a simulation system was created that allows to generate executable AOR simulations and that enables extensive possibilities for simulation execution and evaluation. In addition to this, an existing simulation description language was extended to use it for AOR simulations. In addition, this language was widely improved.

References

[AOR07] Gerd Wagner and and the AOR Modeling and Simulation team. Agent-Object-Relationship (AOR) Modeling and Simulation. Ontologically well-founded modeling and closer-to-reality simulation of complex discrete event scenarios. http://oxygen.informatik.tu-cottbus.de/aor/. 2007-06-24.

[ARGO07] Tigris. ArgoUML. http://argouml.tigris.org/. 2007-05-22.

[Beer04] Jeroen van Luin, Florin Tulba, and Gerd Wagner. Remodeling the Beer Game as an Agent-Object-Relationship Simulation. Proceedings of Workshop 2003: Agent-Based Simulation 5, Lisbon. 2004.

[Bible01] Elliotte Rusty Harold. XML Bible. Wiley. 2nd Edition. 2001.

[GamesAI04] Nathan Combs and Jean-Louis Ardoint. Declarative versus Imperative Paradigms in Games AI. WS04-04. 2004.

[Insel06] Christian Ullenboom. Java ist auch eine Insel. Programmieren mit der Java Standard Edition Version 6. Galileo Press. 6. Auflage. 2006.

[JHLP07] JavaHelp System. Sun Microsystems, Inc.. http://java.sun.com/products/javahelp/. 2007-06-13.

[Klue06] Franziska Klügl. Multiagentensimulation. Informatik Spektrum. 29-6. 2006.

[Krueg06] Guido Krüger. Handbuch der Java-Programmierung. Addison Wesley. 4. Auflage. HTML-Ausgabe 4.0.3. 1998, 2006.

[NS2] ns-2 Wiki Pages. The Network Simulator - ns. http://nsnam.isi.edu/nsnam/. 2007-05-17.

[OTcl95] David Wetherall and Christopher J. Lindblad. Extending Tcl for Dynamic Object-Oriented Programming. Proceedings of the Tcl/Tk Workshop 95, Toronto, Ontario. 1995.

[Oust98] John Ousterhout. Scripting: Higher-level programming for the 21st century.. IEEE Computer. 31(3) (March 1998). 23-30. 1998.

[Raf05] Wolf-Ulrich Raffel. Agentenbasierte Simulation als Verfeinerung der Diskreten-Ereignis-Simulation unter besonderer Berücksichtigung des Beispiels Fahrerloser Transportsysteme. FU Berlin. 2005.

[Repa06] Eric Tartara, M.J. North, T.R. Howe, N.T. Collier, and J.R. Vos. An Introduction To REPAST SIMPHONY Modeling Using a Simple Predator-Prey Example. Proceedings of the Agent 2006 Conference on Social Agents: Results and Prospects, Chicago, USA. 2006.

[Repa07] Mark Altaweel, Nick Collier, Tom Howe, Robert Najlis, Michael North, Miles Parker, Eric Tartara, J.R. Vos, Luc Girardin, and Lazlo Gulyas. Repast Agent Simulation Toolkit. http://repast.sourceforge.net/index.html. 2007-05-22.

[RLY03] Patrick F. Riley and George F. Riley. SPADES - A Distributed Agent Simulation Environment with Software-In-The-Loop Execution. Proceedings of the 2003 Winter Simulation Conference. 2003.

[SETI01] Eric Korpela, Dan Werthimer, David Anderson, Jeff Cobb, and Matt Lebofsky. SETI@HOME - MASSIVELY DISTRIBUTED COMPUTING FOR SETI. IEEE Computer Society. Computing in Science and Engineering. Volume 3, Issue 1 (January 2001). 78-83. 2001.

[SOAP07] SOAP Specifications. W3C. http://www.w3.org/TR/soap/. 2007-06-28.

[SUN04] Interface EventListener. Java 2 Platform Standard Edition 5.0 API Specification. Sun Microsystems, Inc. http://java.sun.com/j2se/1.5.0/docs/api/. 2004.

[Swarm96] Nelson Minar, Roger Burkhart, Chris Langton, and Manor Askenazi. The Swarm simulation system: A toolkit for building multi-agent simulations.. Working Paper 96-06-042, Santa Fe Institute, Santa Fe. 1996.

[Swarm07] Swarm Wiki Pages. SwarmWiki. Swarm Development Group. 2007-05-20.

[Wag03] Gerd Wagner. The Agent-Object-Relationship Meta-Model: Towards a Unified View of State and Behavior.. Information Systems 28:5 (2003), pp. 475-504.. 2003.

[XMI07] XML Metadata Interchange. Object Management Group. http://www.omg.org/technology/documents/formal/xmi.htm. 2007-06-11.

Glossary

AbSim

Agent Based Simulator. See [Raf05] for more information.

AbSimML

Agent Based Simulation Markup Language. Introduced in [Raf05].

AORSML

Agent-Object-Relationship Simulation Markup Language

Java Collections Framework

A Java framework for different types of collections. See http://java.sun.com/j2se/1.5.0/docs/guide/collections/index.html for more information.

UML

Unified Modeling Language

XSLT

XSL Transformations, an XML based transformation language. See [Bible01] for more information.

XMI

XMI - XML Metadata Interchange - is a standard from the Object Management Group (OMG) for exchanging metadata information. The language is based on XML. See [XMI07] for more information.

A. Eidesstattliche Erklärung

Ich erkläre hiermit an Eides statt, dass ich die vorliegende Masterarbeit selbständig und ohne unerlaubte Hilfe angefertigt habe, andere als die angegebenen Quellen und Hilfsmittel nicht benutzt und die den benutzten Quellen wörtlich oder inhaltlich entnommenen Stellen als solche kenntlich gemacht habe.

Cottbus, den _____________ Unterschrift: ______________________________

B. The Classical Beer Game in AORSML

This script describes the classical MIT Beer Game with AORSML. It is a management simulation with a beer supply chain with four nodes. It has a strong hierarchy: every node has one upstream node to order and receive beer from and one downstream node to receive orders from and to delivery beer to. An order takes 7 days to receive and a delivery 14 days. After 7 days - the end of a week - every node decides how much beer to order and calculates costs for current stock and outstanding orders.

<?xml version="1.0" encoding="iso-8859-1"?>
<AORSML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns="http://aors.info" 
        xsi:schemaLocation="http://aors.info aorsml.xsd" 
        title="BeerGame_v1">
  <SimulationParameters>
    <Parameter name="stopTime" type="int" value="28"/>
    <Parameter name="cycleDuration" type="int" value="7"/>
    <Parameter name="timeUnit" type="String" value="days"/>
    <Parameter name="cycleRealTimeDelay" type="long" value="1000"/>
  </SimulationParameters>
  <EntityTypes>
    <AgentType name="SupplyChainNode">
      <SelfBeliefProperty name="inventory" type="int" defaultvalue="10"/>
      <SelfBeliefProperty name="currentSalesOrderQuantity" type="int"/>
      <SelfBeliefProperty name="backorderQuantity" type="int"/>
      <SelfBeliefProperty name="costs" type="double"/>
    </AgentType>
    <ActionEventType name="ShipBeer" actorType="SupplyChainNode">
      <Property name="quantity" type="int"/>
    </ActionEventType>
    <PerceptionSignalEventType name="ShippingDelay">
      <Property name="shipperID" type="int"/>
      <Property name="quantity" type="int"/>
    </PerceptionSignalEventType>
    <ExogenousEventType name="CustomerDemand">
      <periodicity language="Java">7</periodicity>
      <stopCondition language="Java">occurrenceTime &gt; 70</stopCondition>
    </ExogenousEventType>
    <PerceptionEventType name="BeerDelivery" perceptor="SupplyChainNode">
      <Property name="quantity" type="int"/>
    </PerceptionEventType>
    <PerceptionEventType name="CustomerOrder" perceptor="SupplyChainNode">
      <Property name="quantity" type="int"/>
    </PerceptionEventType>
    <PeriodicTimeEventType name="EndOfWeek">
      <periodicity language="Java">7</periodicity>
      <stopCondition language="Java">occurrenceTime &gt; 70</stopCondition>
    </PeriodicTimeEventType>
    <MessageType name="Order" receiver="SupplyChainNode" 
                              sender="SupplyChainNode">
      <Property name="quantity" type="int"/>
    </MessageType>
  </EntityTypes>
  <InitialState>
    <AgentInstance instanceOf="SupplyChainNode" name="Retailer" id="1">
      <SelfBeliefSlot selfBeliefProperty="inventory" value="10"/>
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek1">
        <Slot property="startingTime" value="7"/>
        <Slot property="agentType" value="SupplyChainNode"/>
        <Slot property="agentID" value="1"/>
      </EventInstance>
    </AgentInstance>
    <AgentInstanceSet instanceOf="SupplyChainNode" 
                      startID="2" amount="3" name="Distributor">
      <SelfBeliefSlot selfBeliefProperty="inventory" value="10"/>
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek">
        <Slot property="startingTime" value="7"/>
        <Slot property="agentType" value="SupplyChainNode"/>
      </EventInstance>
    </AgentInstanceSet>
    <AgentInstance instanceOf="SupplyChainNode" 
                   name="RawMaterialsSupplier" id="5">
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek5">
        <Slot property="startingTime" value="7"/>
        <Slot property="agentType" value="SupplyChainNode"/>
        <Slot property="agentID" value="5"/>
      </EventInstance>
    </AgentInstance>
    <EventInstance stereotype="ExogenousEvent" 
                   instanceOf="CustomerDemand" name="AutomaticBeerDemand">
      <Slot property="startingTime" value="7"/>
    </EventInstance>
  </InitialState>
  <Rules>
    <EnvironmentRule name="RuleCreateShippingDelay">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="ShipBeer" alias="shipBeer"/>
      </triggeringEventExpr>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShippingDelay" eventType="event">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                             valueExpression="shipBeer.occurrenceTime + 7"/>
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="shipBeer.quantity"/>
          <PropertyValueSlot eventProperty="shipperID" 
                             valueExpression="shipBeer.actorID"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </EnvironmentRule>
    <EnvironmentRule name="RuleShipBeer">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="ShippingDelay" alias="shippingDelay"/>
      </triggeringEventExpr>
      <resultingEventExpr>
        <AtomicEventExpr eventName="BeerDelivery" eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                      valueExpression="shippingDelay.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="shippingDelay.shipperID-1"/>
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="shippingDelay.quantity"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </EnvironmentRule>
    <EnvironmentRule name="RuleCustomerDemand">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="CustomerDemand" alias="customerDemand"/>
      </triggeringEventExpr>
      <resultingEventExpr>
        <AtomicEventExpr eventName="CustomerOrder" eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                      valueExpression="customerDemand.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="1"/>
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="Random.uniformInt(1, 10)"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </EnvironmentRule>
    <AgentRule name="RuleIncomingBeerDelivery">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="BeerDelivery" alias="beerDelivery"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <stateEffects language="Java">
        <assign property="node.inventory" 
                valueExpression="node.inventory + beerDelivery.quantity"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleIncomingOrder">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="Order" 
                         eventType="message" alias="order"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <stateEffects language="Java">
        <assign property="node.currentSalesOrderQuantity" 
                valueExpression="node.currentSalesOrderQuantity 
                                 + order.quantity"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleIncomingCustomerOrder">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="CustomerOrder" 
                         eventType="perception" alias="order"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <stateEffects language="Java">
        <assign property="node.currentSalesOrderQuantity"  
                valueExpression="node.currentSalesOrderQuantity 
                                 + order.quantity"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleShippingAllOrders">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">
        (node.id != 1) &amp;&amp; 
        (node.id != 5) &amp;&amp; 
        node.inventory &gt;= (node.currentSalesOrderQuantity 
                             + node.backorderQuantity) 
        &amp;&amp; ((node.currentSalesOrderQuantity 
                   + node.backorderQuantity) &gt; 0)
      </condition>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                      valueExpression="node.currentSalesOrderQuantity 
                                             + node.backorderQuantity"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      <stateEffects language="Java">
        <assign property="node.inventory" 
                valueExpression="node.inventory  
                                - (node.currentSalesOrderQuantity 
                                + node.backorderQuantity)"/>
        <assign property="node.backorderQuantity" valueExpression="0"/>
        <assign property="node.currentSalesOrderQuantity" 
                valueExpression="0"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleShippingAvailableAmount">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">
        (node.id != 1) &amp;&amp; 
        (node.id != 5) &amp;&amp; 
        node.inventory &lt; (node.currentSalesOrderQuantity 
        + node.backorderQuantity) 
        &amp;&amp; (node.inventory &gt; 0)
      </condition>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="node.inventory"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      <stateEffects language="Java">
        <assign property="node.backorderQuantity" 
                valueExpression="(node.backorderQuantity 
                                + node.currentSalesOrderQuantity) 
                                - node.inventory"/>
        <assign property="node.inventory" valueExpression="0"/>
        <assign property="node.currentSalesOrderQuantity" 
                valueExpression="0"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleShippingAllCustomerOrders">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">
        (node.id == 1) &amp;&amp; 
        node.inventory &gt;= (node.currentSalesOrderQuantity
        + node.backorderQuantity)
      </condition>
      <stateEffects language="Java">
        <assign property="node.inventory" 
                valueExpression="node.inventory - 
                                (node.currentSalesOrderQuantity 
                                + node.backorderQuantity)"/>
        <assign property="node.backorderQuantity" valueExpression="0"/>
        <assign property="node.currentSalesOrderQuantity" 
                valueExpression="0"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleShippingAvailableAmountToCustomer">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">
        (node.id == 1) &amp;&amp; 
        node.inventory &lt; (node.currentSalesOrderQuantity 
        + node.backorderQuantity)
      </condition>
      <stateEffects language="Java">
        <assign property="node.backorderQuantity" 
               valueExpression="(node.backorderQuantity 
                               + node.currentSalesOrderQuantity) 
                               - node.inventory"/>
        <assign property="node.inventory" valueExpression="0"/>
        <assign property="node.currentSalesOrderQuantity" 
                valueExpression="0"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleShippingRawMaterials">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">
        (node.id == 5) &amp;&amp; 
        (node.currentSalesOrderQuantity &gt; 0)</condition>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                      valueExpression="node.currentSalesOrderQuantity"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </AgentRule>
    <AgentRule name="RuleOrderingStock">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">node.id != 5</condition>
      <resultingEventExpr>
        <AtomicEventExpr eventName="Order" eventType="message">
          <PropertyValueSlot eventProperty="receiverID" 
                             valueExpression="node.id+1"/>
          <PropertyValueSlot eventProperty="duration" 
                             valueExpression="7"/>
          <PropertyValueSlot eventProperty="reliability" 
                             valueExpression="1"/>
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="Random.uniformInt(1, 10)"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </AgentRule>
    <AgentRule name="RuleCalculatingCosts">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="EndOfWeek" alias="eow"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <condition language="Java">node.id != 5</condition>
      <stateEffects language="Java">
        <assign property="node.costs" 
                valueExpression="node.costs + (1 * node.inventory) 
                                + (2 * node.backorderQuantity)"/>
      </stateEffects>
    </AgentRule>
  </Rules>
</AORSML>

C. An Advanced Beer Game Version

The following script introduces an advanced Beer Game version using new AORSML language features. The game starts exactly as the basic version. After a certain amount of time, a new supply chain node appears and gets inserted into the supply chain. Some time later, the same node disappears. This version shows how to use the create and destroy elements and how to model inserting and removing of nodes into and from the supply chain. The script only fully shows the new elements that have been necessary for this version of the Beer Game. All elements that are equal as in the basic game are shown abbreviated.

<AORSML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns="http://aors.info" 
        xsi:schemaLocation="http://aors.info aorsml.xsd" title="BeerGame_v3">
  <SimulationParameters>
    ...
  </SimulationParameters>
  <EntityTypes>
    <AgentType name="SupplyChainNode">
      <SelfBeliefProperty name="inventory" type="int" defaultvalue="10"/>
      <SelfBeliefProperty name="currentSalesOrderQuantity" type="int"/>
      <SelfBeliefProperty name="backorderQuantity" type="int"/>
      <SelfBeliefProperty name="costs" type="double"/>
      <SelfBeliefProperty name="orderFromNode" type="int" 
                          defaultvalue="id+1"/>
      <SelfBeliefProperty name="shipToNode" type="int" defaultvalue="id-1"/>
    </AgentType>
    <ActionEventType name="ShipBeer" actorType="SupplyChainNode">
      ...
    </ActionEventType>
    <PerceptionSignalEventType name="ShippingDelay">
      ...
    </PerceptionSignalEventType>
    <ExogenousEventType name="CustomerDemand">
      ...
    </ExogenousEventType>
    <ExogenousEventType name="AppearingNode">
      <periodicity language="Java">7</periodicity>
      <stopCondition language="Java">occurrenceTime &gt; 21</stopCondition>
    </ExogenousEventType>
    <ExogenousEventType name="DisappearingNode">
      <periodicity language="Java">7</periodicity>
      <stopCondition language="Java">occurrenceTime &gt; 35</stopCondition>
    </ExogenousEventType>
    <PerceptionEventType name="BeerDelivery" perceptor="SupplyChainNode">
      ...
    </PerceptionEventType>
    <PerceptionEventType name="CustomerOrder" perceptor="SupplyChainNode">
      ...
    </PerceptionEventType>
    <PerceptionEventType name="ChangingUpStreamNode" 
                         perceptor="SupplyChainNode">
      <Property name="newOrderFromNode" type="int"/>
    </PerceptionEventType>
    <PerceptionEventType name="ChangingDownStreamNode" 
                         perceptor="SupplyChainNode">
      <Property name="newShipToNode" type="int"/>
    </PerceptionEventType>
    <PeriodicTimeEventType name="EndOfWeek">
      ...
    </PeriodicTimeEventType>
    <MessageType name="Order" receiver="SupplyChainNode" 
                              sender="SupplyChainNode">
      ...
    </MessageType>
  </EntityTypes>
  <InitialState>
    <AgentInstance instanceOf="SupplyChainNode" name="retailer" id="1">
      <SelfBeliefSlot selfBeliefProperty="inventory" value="10"/>
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek1">
        <Slot property="startingTime" value="0"/>
      </EventInstance>
    </AgentInstance>
    <AgentInstance instanceOf="SupplyChainNode" 
                   name="rawMaterialsSupplier" id="5">
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek5">
        <Slot property="startingTime" value="0"/>
      </EventInstance>
    </AgentInstance>
    <AgentInstanceSet instanceOf="SupplyChainNode" startID="2" 
                      amount="3" name="distributor">
      <SelfBeliefSlot selfBeliefProperty="inventory" 
                      value="distributor.id*10"/>
      <EventInstance stereotype="PeriodicTimeEvent" 
                     instanceOf="EndOfWeek" name="endOfWeek">
        <Slot property="startingTime" value="0"/>
      </EventInstance>
    </AgentInstanceSet>
    <EventInstance stereotype="ExogenousEvent" 
                   instanceOf="CustomerDemand" name="customerDemand">
      ...
    </EventInstance>
    <EventInstance stereotype="ExogenousEvent" 
                   instanceOf="AppearingNode" 
                   name="appearingNode">
      <Slot property="startingTime" value="21"/>
    </EventInstance>
    <EventInstance stereotype="ExogenousEvent" 
                   instanceOf="DisappearingNode" 
                   name="disappearingNode">
      <Slot property="startingTime" value="35"/>
    </EventInstance>
  </InitialState>
  <Rules>
    <EnvironmentRule name="RuleAppearingNode">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="AppearingNode" 
                         alias="appearingNode"/>
      </triggeringEventExpr>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ChangingUpStreamNode" 
                         eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                   valueExpression="appearingNode.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="newOrderFromNode" 
                             valueExpression="6"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="2"/>
        </AtomicEventExpr>
        <AtomicEventExpr eventName="ChangingDownStreamNode" 
                         eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                   valueExpression="appearingNode.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="newShipToNode" 
                             valueExpression="6"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="3"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      <createPhysicalObject>
        <AgentInstance instanceOf="SupplyChainNode" 
                       name="newNode" id="6">
          <SelfBeliefSlot selfBeliefProperty="orderFromNode" value="3"/>
          <SelfBeliefSlot selfBeliefProperty="shipToNode" value="2"/>
          <EventInstance stereotype="PeriodicTimeEvent" 
                         instanceOf="EndOfWeek" name="endOfWeek6">
            <Slot property="startingTime" value="21"/>
          </EventInstance>
        </AgentInstance>
      </createPhysicalObject>
    </EnvironmentRule>
    <EnvironmentRule name="RuleDisappearingNode">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="DisappearingNode" 
                         alias="disappearingNode"/>
      </triggeringEventExpr>
      <resultingEventExpr>
        <AtomicEventExpr eventName="ChangingUpStreamNode" 
                         eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                    valueExpression="disappearingNode.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="newOrderFromNode" 
                             valueExpression="3"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="2"/>
        </AtomicEventExpr>
        <AtomicEventExpr eventName="ChangingDownStreamNode" 
                         eventType="perception">
          <PropertyValueSlot eventProperty="occurrenceTime" 
                    valueExpression="disappearingNode.occurrenceTime - 1"/>
          <PropertyValueSlot eventProperty="newShipToNode" 
                             valueExpression="2"/>
          <PropertyValueSlot eventProperty="perceptorID" 
                             valueExpression="3"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      <destroyPhysicalObject>
        <Agent type="SupplyChainNode" id="6"/>
      </destroyPhysicalObject>
    </EnvironmentRule>
    <EnvironmentRule name="RuleCreateShippingDelay">
      ...
    </EnvironmentRule>
    <EnvironmentRule name="RuleShipBeer">
      ...
    </EnvironmentRule>
    <EnvironmentRule name="RuleCustomerDemand">
      ...
    </EnvironmentRule>
    <AgentRule name="RuleIncomingBeerDelivery">
      ...
    </AgentRule>
    <AgentRule name="RuleIncomingOrder">
      ...
    </AgentRule>
    <AgentRule name="RuleIncomingCustomerOrder">
      ...
    </AgentRule>
    <AgentRule name="RuleShippingAllOrders">
      ...
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                   valueExpression="node.currentSalesOrderQuantity 
                                    + node.backorderQuantity"/>
          <PropertyValueSlot eventProperty="receiverID" 
                             valueExpression="node.shipToNode"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      ...
    </AgentRule>
    <AgentRule name="RuleShippingAvailableAmount">
      ...
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="node.inventory"/>
          <PropertyValueSlot eventProperty="receiverID" 
                             valueExpression="node.shipToNode"/>
        </AtomicEventExpr>
      </resultingEventExpr>
      ...
    </AgentRule>
    <AgentRule name="RuleShippingAllCustomerOrders">
      ...
    </AgentRule>
    <AgentRule name="RuleShippingAvailableAmountToCustomer">
      ...
    </AgentRule>
    <AgentRule name="RuleShippingRawMaterials">
      ...
      <resultingEventExpr>
        <AtomicEventExpr eventName="ShipBeer" eventType="action">
          <PropertyValueSlot eventProperty="quantity" 
                        valueExpression="node.currentSalesOrderQuantity"/>
          <PropertyValueSlot eventProperty="receiverID" 
                             valueExpression="node.shipToNode"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </AgentRule>
    <AgentRule name="RuleOrderingStock">
      ...
      <resultingEventExpr>
        <AtomicEventExpr eventName="Order" eventType="message">
          <PropertyValueSlot eventProperty="receiverID" 
                             valueExpression="node.orderFromNode"/>
          <PropertyValueSlot eventProperty="duration" valueExpression="7"/>
          <PropertyValueSlot eventProperty="reliability" 
                             valueExpression="1"/>
          <PropertyValueSlot eventProperty="quantity" 
                             valueExpression="Random.uniformInt(1, 10)"/>
        </AtomicEventExpr>
      </resultingEventExpr>
    </AgentRule>
    <AgentRule name="RuleCalculatingCosts">
      ...
    </AgentRule>
    <AgentRule name="RuleChangingDownStreamNode">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="ChangingDownStreamNode" 
                         alias="newDownStreamNode"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <stateEffects language="Java">
        <assign property="node.shipToNode" 
                valueExpression="newDownStreamNode.newShipToNode"/>
      </stateEffects>
    </AgentRule>
    <AgentRule name="RuleChangingUpStreamNode">
      <triggeringEventExpr>
        <AtomicEventExpr eventName="ChangingUpStreamNode" 
                         alias="newUpStreamNode"/>
      </triggeringEventExpr>
      <involvedPhysicalObject>
        <Agent type="SupplyChainNode" alias="node"/>
      </involvedPhysicalObject>
      <stateEffects language="Java">
        <assign property="node.orderFromNode" 
                valueExpression="newUpStreamNode.newOrderFromNode"/>
      </stateEffects>
    </AgentRule>
  </Rules>
</AORSML>

D. AORSML Schema

This listing shows the complete AORSML Schema as used to validate AORSML files with AOR-JSim.

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- created by Andreas Post (BTU Cottbus) version 1.5 -->
<xs:schema xmlns="http://aors.info" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://aors.info" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">
  <xs:element name="AORSML">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="SimulationParameters" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="EntityTypes" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="InitialState" minOccurs="1" maxOccurs="1"/>
        <xs:element ref="Rules" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="title" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SimulationParameters">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Parameter" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Parameter">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="int"/>
            <xs:enumeration value="float"/>
            <xs:enumeration value="long"/>
            <xs:enumeration value="double"/>
            <xs:enumeration value="boolean"/>
            <xs:enumeration value="byte"/>
            <xs:enumeration value="short"/>
            <xs:enumeration value="char"/>
            <xs:enumeration value="String"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="EntityTypes">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="AgentType" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ObjectType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ActionEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="CausedEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="PerceptionSignalEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ExogenousEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="PerceptionEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ReminderEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="PeriodicTimeEventType" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="MessageType" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentType">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Property" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="SelfBeliefProperty" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="defaultView" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="views" minOccurs="0" maxOccurs="1"/>
      </xs:choice>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ObjectType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
        <xs:element ref="defaultView" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="views" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ActionEventType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="actorType" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="CausedEventType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="PerceptionSignalEventType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ExogenousEventType">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Property" maxOccurs="unbounded"/>
        <xs:element ref="periodicity"/>
        <xs:element ref="stopCondition"/>
      </xs:choice>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="PerceptionEventType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="perceptor" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ReminderEventType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="PeriodicTimeEventType">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Property" maxOccurs="unbounded"/>
        <xs:element ref="periodicity"/>
        <xs:element ref="stopCondition"/>
      </xs:choice>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="MessageType">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Property" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="sender" type="xs:string" use="required"/>
      <xs:attribute name="receiver" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="InitialState">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="AgentInstance" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="AgentInstanceSet" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ObjectInstance" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ObjectInstanceSet" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EventInstance" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EventInstanceSet" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentInstance">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Slot" maxOccurs="unbounded"/>
        <xs:element ref="SelfBeliefSlot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EventInstance" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentInstanceSet">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="SelfBeliefSlot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EventInstance" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="amount" type="xs:string" use="required"/>
      <xs:attribute name="startID" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ObjectInstance">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ObjectInstanceSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="amount" type="xs:string" use="required"/>
      <xs:attribute name="startID" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="EventInstance">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="stereotype" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="ExogenousEvent"/>
            <xs:enumeration value="CausedEvent"/>
            <xs:enumeration value="ReminderEvent"/>
            <xs:enumeration value="PeriodicTimeEvent"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="EventInstanceSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="instanceOf" type="xs:string" use="required"/>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="startID" type="xs:string" use="required"/>
      <xs:attribute name="endID" type="xs:string" use="required"/>
      <xs:attribute name="stereotype" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="ExogenousEvent"/>
            <xs:enumeration value="CausedEvent"/>
            <xs:enumeration value="ReminderEvent"/>
            <xs:enumeration value="PeriodicTimeEvent"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="Rules">
    <xs:complexType>
      <xs:choice minOccurs="1" maxOccurs="unbounded">
        <xs:element ref="EnvironmentRule" 
                    minOccurs="1" maxOccurs="unbounded"/>
        <xs:element ref="AgentRule" minOccurs="1" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="Property">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="int"/>
            <xs:enumeration value="float"/>
            <xs:enumeration value="long"/>
            <xs:enumeration value="double"/>
            <xs:enumeration value="boolean"/>
            <xs:enumeration value="byte"/>
            <xs:enumeration value="short"/>
            <xs:enumeration value="char"/>
            <xs:enumeration value="String"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="defaultvalue" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Slot">
    <xs:complexType>
      <xs:attribute name="property" type="xs:string" use="required"/>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SelfBeliefProperty">
    <xs:complexType>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="int"/>
            <xs:enumeration value="float"/>
            <xs:enumeration value="long"/>
            <xs:enumeration value="double"/>
            <xs:enumeration value="boolean"/>
            <xs:enumeration value="byte"/>
            <xs:enumeration value="short"/>
            <xs:enumeration value="char"/>
            <xs:enumeration value="String"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="defaultvalue" type="xs:string" use="optional"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SelfBeliefSlot">
    <xs:complexType>
      <xs:attribute name="selfBeliefProperty" 
                    type="xs:string" use="required"/>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="EnvironmentRule">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="triggeringEventExpr"/>
        <xs:element ref="involvedPhysicalObject" minOccurs="0"/>
        <xs:element ref="condition" minOccurs="0"/>
        <xs:element ref="resultingEventExpr" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="createPhysicalObject" minOccurs="0"/>
        <xs:element ref="destroyPhysicalObject" minOccurs="0"/>
        <xs:element ref="stateEffects" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentRule">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="triggeringEventExpr"/>
        <xs:element ref="involvedPhysicalObject" minOccurs="0"/>
        <xs:element ref="condition" minOccurs="0"/>
        <xs:element ref="resultingEventExpr" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="stateEffects" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="triggeringEventExpr">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="AtomicEventExpr"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="AtomicEventExpr">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="PropertyValueSlot" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="eventName" use="required"/>
      <xs:attribute name="eventType">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="event"/>
            <xs:enumeration value="perception"/>
            <xs:enumeration value="action"/>
            <xs:enumeration value="reminderevent"/>
            <xs:enumeration value="message"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
      <xs:attribute name="alias"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="PropertyValueSlot">
    <xs:complexType>
      <xs:attribute name="eventProperty" use="optional"/>
      <xs:attribute name="agentProperty" use="optional"/>
      <xs:attribute name="valueExpression" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="involvedPhysicalObject">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Agent"/>
        <xs:element ref="Object"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="resultingEventExpr">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="AtomicEventExpr" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="periodicity">
    <xs:complexType mixed="true">
      <xs:attribute name="language" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="Java"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="stopCondition">
    <xs:complexType mixed="true">
      <xs:attribute name="language" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="Java"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="condition">
    <xs:complexType mixed="true">
      <xs:attribute name="language" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="Java"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="stateEffects">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="assign" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="GroupAssign" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="language" use="required">
        <xs:simpleType>
          <xs:restriction base="xs:string">
            <xs:enumeration value="Java"/>
          </xs:restriction>
        </xs:simpleType>
      </xs:attribute>
    </xs:complexType>
  </xs:element>
  <xs:element name="assign">
    <xs:complexType>
      <xs:attribute name="property" use="required"/>
      <xs:attribute name="valueExpression" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="GroupAssign">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="AgentSet"/>
        <xs:element ref="ObjectSet"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="createPhysicalObject">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="AgentInstance" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="AgentInstanceSet" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ObjectInstance" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ObjectInstanceSet" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="destroyPhysicalObject">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Agent"/>
        <xs:element ref="AgentSet"/>
        <xs:element ref="Object"/>
        <xs:element ref="ObjectSet"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="Agent">
    <xs:complexType>
      <xs:attribute name="type" type="xs:string"/>
      <xs:attribute name="id" type="xs:string"/>
      <xs:attribute name="alias" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="assign" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string"/>
      <xs:attribute name="startID" type="xs:string"/>
      <xs:attribute name="amount" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Object">
    <xs:complexType>
      <xs:attribute name="type" type="xs:string"/>
      <xs:attribute name="id" type="xs:string"/>
      <xs:attribute name="alias" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ObjectSet">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="assign" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string"/>
      <xs:attribute name="startID" type="xs:string"/>
      <xs:attribute name="amount" type="xs:string"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="defaultView">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="geometricForm" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="views">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="View" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="View">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="scale" use="required"/>
      <xs:attribute name="scalevalue" use="required"/>
      <xs:attribute name="geometricForm" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

E. XML Schema for Simulation Output Language

This appendix shows the created XML Schema for AOR-JSim XML based output files.

<?xml version="1.0" encoding="iso-8859-1"?>
<!-- created by Andreas Post (BTU Cottbus) version 1.0 -->
<xs:schema xmlns="http://aors.info" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://aors.info" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">
  <xs:element name="SimulationOutput">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="SimulationStep" 
                    minOccurs="1" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="simulationName" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SimulationStep">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="EnvironmentSimulatorStep" 
                    minOccurs="1" maxOccurs="1"/>
        <xs:element ref="AgentSimulatorStep" 
                    minOccurs="1" maxOccurs="unbounded"/>
        <xs:element ref="SimulationState" minOccurs="1" maxOccurs="1"/>
      </xs:sequence>
      <xs:attribute name="clock" type="xs:string" use="required"/>
      <xs:attribute name="time" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="EnvironmentSimulatorStep">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Event" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ActionEvent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="Message" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentSimulatorStep">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="InternalEvent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="Perception" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="Message" minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SimulationState">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Objects" minOccurs="0" maxOccurs="1"/>
        <xs:element ref="Agents" minOccurs="0" maxOccurs="1"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Event">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EnvironmentRule" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ActionEvent">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EnvironmentRule" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="actorType" type="xs:string" use="required"/>
      <xs:attribute name="actorID" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="InternalEvent">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="AgentRule" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Perception">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="AgentRule" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="perceptorType" type="xs:string" use="required"/>
      <xs:attribute name="perceptorID" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Message">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="EnvironmentRule" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="AgentRule" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="senderType" type="xs:string" use="required"/>
      <xs:attribute name="senderID" type="xs:string" use="required"/>
      <xs:attribute name="receiverType" type="xs:string" use="required"/>
      <xs:attribute name="receiverID" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="MessagePerception">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="senderType" type="xs:string" use="required"/>
      <xs:attribute name="senderID" type="xs:string" use="required"/>
      <xs:attribute name="receiverType" type="xs:string" use="required"/>
      <xs:attribute name="receiverID" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="EnvironmentRule">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ResultingEvents" 
                    minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="CreateAgent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="CreateObject" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="DestroyAgent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="DestroyObject" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="AgentRule">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="ResultingEvents" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Slot">
    <xs:complexType>
      <xs:attribute name="property" type="xs:string" use="required"/>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="SelfBeliefSlot">
    <xs:complexType>
      <xs:attribute name="selfbeliefproperty" 
                    type="xs:string" use="required"/>
      <xs:attribute name="value" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="ResultingEvents">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
          <xs:element ref="Event" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="InternalEvent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="Perception" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="ActionEvent" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="Message" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="MessagePerception" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:choice>
    </xs:complexType>
  </xs:element>
  <xs:element name="CreateAgent">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="SelfBeliefSlot" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="CreateObject">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="DestroyAgent">
    <xs:complexType>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="DestroyObject">
    <xs:complexType>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Agents">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Agent" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Objects">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Object" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:element name="Agent">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element ref="SelfBeliefSlot" 
                    minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
  <xs:element name="Object">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="Slot" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
      <xs:attribute name="name" type="xs:string" use="required"/>
      <xs:attribute name="type" type="xs:string" use="required"/>
      <xs:attribute name="id" type="xs:string" use="required"/>
    </xs:complexType>
  </xs:element>
</xs:schema>    


[1] See http://www.swarm.org/wiki/Swarm_Development_Group for more information on the swarm development group (2007-05-20).

[2] Latest belongs to the time this work was written. There may be another version available, but Repast S was the current release at creation time of this thesis.

[3] There is no definition until now what happens if two events have the same occurrence time. Until now, the order of concurrent events will be determined by random influence.

[4] A message will directly be forwarded by the environment simulator without any processing to the receiving agent.

[5] In fact, ns-2 uses a hybrid approach. The simulation system offers libraries for a lot of standard network elements. For usual network simulations it will be enough to write simulation scripts. But for extended simulation tasks, for instance own network protocols, it is also possible to implement new classes in C++ and to use them.

[6] In the generated Java code, there will be a static field for every simulation parameter in the simulation main class. Since this simulation main class is available to every other created class, all parameters can easily be retrieved.

[7] Internally, simulating one cycle just increments the simulation clock by 1. This means, every simulation cycle has a length of 1 time units.

[8] No cause means, that there is nothing within a specific AOR simulation that can be a cause for an exogenous event. There could be another simulation that tries to model weather conditions, then there might be events that result in wind events. But for a sailing simulation wind events can occur without being caused by any other event.

[9] As mentioned above, time declarations in a simulation file must always refer to the cycleDuration parameter, that must be specified under SimulationParameters.

[10] If the property was defined with a default value and there should be no other value, it is not necessary to set a value for this property.

[11] The tuple {type, id} is used internally as a unique identifier for agents and objects. Thus agents (objects) of different types may have the same identifiers but not agents (objects) of the same entity type.

[12] Only periodic events and exogenous events use the property startingTime, since it marks the first occurrence of the event. All other events use the property occurrenceTime.

[13] Currently it is only possible to have a single triggering event. An extension could be to allow multiple events as a combined trigger for a rule. This requires small changes to the XML code, but large changes in the underlying simulation system. This could be a good feature for future projects.

[14] Sure, it is still possible that a file may cause errors when compiling it, since validating the given file doesn't checks values of text nodes for plausibility. But validating ensures that the file's structure is correct.

[15] In fact, the amount of ordered beer has a strong influence on the result of the whole simulation. See [Beer04] for some simulation results.

[16] In fact, there are more rules, but the rules shown in Figure 7, “Internal AOR model of a SupplyChainNode.” will be sufficient to explain the modeling of an agent in the Beer Game in AOR.

[17] In the current version, the environment simulator only forwards messages to the agent specified with the receiver id and type. Thus, it is not possible to check in the environment simulator if a message comes from a certain sender like the factory node and process it in another way. It is possible to create other constructs for the factory node for ordering beer than sending a message, but for this solution, a fifth node is necessary to receive the message and ship back beer.

[18] Properties from father entity types don't need to get specified for any new entity type. When defining an instance of such an entity type, all these basic properties are available. In the simulation language, this language is based on - AbSimML - it was necessary to specify all needed properties, including basic properties. To improve the usability of the language this was changed. Furthermore, to remove some sources of errors, most basic properties now must be specified for an entity instance as an attribute. Since using an XML Schema for AORSML, it was possible to mark these important properties as required, thus, users are forced to specify values for them.

[19] Sure, an agent can influence it's environment by doing actions and sending messages. But, the actual influence on other agents or objects will be created when processing these actions and messages with the help of the environment simulator.

[20] The word pointers is not meant as pointers in sense of usually usage in typical programming languages. This can be modeled later in several ways, but how is not important here.

[21] In fact, there is a third exception package under the obsim package. Since the complete obsim package will be removed, this exception package will also be removed.

[22] The "natural" ending of a simulation is either the case that there are no more events to simulate or the current simulation time reaches a predefined stop time.

[23] The SimulationSystem class has no influence on the results of a simulation. It holds the instance of the environment simulator and of all agent simulators and can therefore realize the communication between them. But it does not create or process any event except while initializing the simulation.

[24] Logically, the action and message sets can also be empty in the case that an agent simulator has no externally visible reaction in a simulation cycle.

[25] An exogenous event can be used for all events that cannot be created directly by agents and that are not a result of any other event. For instance this can be some wind effect on a tennis player agent in a sports simulation.

[26] Since exogenous events are periodic events, they can occur from time to time. Thus, after an exogenous event occurred it is necessary to compute the time of the next occurrence of this event. The time between two occurrences can hereby be defined in the simulation definition file. Finally, after computing the next occurrence, this event will be placed inside a usual event list, that will be processed in the next step.

[27] Conditions can be used to specify special constraints for some events. The reaction on an event may also be bound to the state of some agent or object.

[28] The main reason, an agent gets controlled by an agent simulator is that the processing logic should be decoupled from the entity agent. An agent should not know about a simulation system or about how information will be transferred between simulation entities of between an agent and the environment. Furthermore, an agent simulator may be implemented in several ways, for instance including a user interface. With this approach, an agent remains a simulation entity.

[29] In fact, this step is split up to three single methods, but since their processing order is not important, step (5) shows all three methods as one step.

[30] Yet, in some cases AbSim reacts with error messages if the user is trying to use some of the programs functions. For instance, the program re-stores an already transformed AbSimML file but pops up an error message when trying to create Java code from it. The same function works fine when not using a project file.

[31] Used to check if the project file was created with the same version of the program. Currently only displays a warning if versions don't match. But, it would also be possible in the future to use this parameter for enabling some backward compatibility if a project file will be opened with a later version of the software.

[32] In General, it is not necessary to edit the generated source code. But, to include extra functionalities in the source code that cannot be generated automatically from AORSML, this option is enabled.

[33] An idea is to create a JavaScript version of the simulator to embed it into a website. This version would profit from an XML based project file.

[34] Since the user can specify the names of all entities in an AORSML simulation definition, the file name is not sufficient for assigning it to a specific entity. For instance, a file like ShipBeer.java from the beer game simulation doesn't tells, if this class is an action, event or even an agent.

[35] AOR-JSim only starts a simulation and can influence the execution by pausing it, force the simulation to run for a defined amount of time and, of course, continue a paused simulation. But the actual execution of a simulation step cannot be influenced or directly observed by AOR-JSim.

[36] For simplicity, Figure 29, “The embedding of the logger interface.” only shows some example notification methods. The real Java class has a much larger set with methods for every process in the simulation.

[37] The time attribute consists of a time value and a value for the time unit. The time value gets computed by the value for the duration of a cycle and the current simulation cycle. The cycle duration and the time unit must be specified in the AOR simulation file.

[38] Every event can have an arbitrary amount of rules. For every rule it is possible to specify conditions which must be true for the rule to apply. If no condition is specified, the rule will always be executed.

[39] The message object itself is transferred to the logger as argument of the notifyMessage method. Hence, it is possible to access all fields of the message objects class.

[40] In fact, it is possible to create or destroy agents and objects during a running simulation as the introduced language extensions in Section 3.6, “Introducing Advanced Language Extensions” show.

[41] The width of the chart in turn depends on the size of the chart window and will be computed every time the window has to be repainted.

[42] For a symmetric chart image, the gap before the first bar and after the last bar are exactly half the size of the gap.

[43] Intel Pentium 4, CPU 2.64GHz, 512MB RAM

[45] For instance, several parts of the simulation may run on the same computer but as independent applications in different virtual machines if written in Java.

[46] In this case it would also be necessary that every agent simulator has the set of simulation classes in his own language.