This document is out of date. In particular, the virtual agency
described has been rolled into tkeden
, as the feature
seems to be in use where modellers have many similar buttons to
create, whether the model is distributed or not. Before using virtual
agents, you might like to note that some modellers have reservations
about the virtual agency facility (due to the design which seems to be
a rather procedurally-styled pre-processing hack with obscure syntax
which prohibits nesting of agents among other things). The
dtkeden
tool now differs from tkeden
in the
following respects: it allows distributed (socket-based) communication
between dtkeden
processes, and the %lsd notation is
provided to allow control of the flow of data between server and
clients.
This document includes information about getting started, running the tool on the computer systems in the Department of Computer Science, the four modes for agent interaction and the mechanisms for sending messages between servers and clients. There is also information concerning the built-in support for the LSD notation and the mechanisms for controlling virtual agency available in the tool.
In addition, some LSD concepts (oracle, handle and state) are implemented in dtkeden. An oracle refers to the privilege of an agent to observe a variable (considered as an observable), and a handle refers to an agents privilege to change a variable (observable). A special automated agent, the LSD Agent, is located at the server in dtkeden. This agent has responsibility for the management of access privileges for variables. When a request to access (reference or alteration) a variable comes from a client to the server, the LSD Agent will check the privilege of the sender for their access permission to that variable. At the same time, if a change to an observable is made, the LSD Agent will propagate this change to all other agents who are authorised to receive it.
Each dtkeden client is identified by a login name and communication from this client to the server is attributed to an appropriately named virtual agent. Virtual agency brings some of the advantages of object-oriented classes to Empirical Modelling. There is no instantiation in the current version of tkeden. The duplication of similar definitive scripts can only be achieved by hand, or by the command execute (if the dynamic creation of scripts is required). For example, if you want to create 150 buttons in a screen, 150 blocks of similar scripts for SCOUT have to be coded. In dtkeden, virtual agency can be applied to this example. It is as if dtkeden instantiates several copies of a single definitive script, prefixing each variable name by virtual agent names to distinguish them. In this context, the usage of virtual agency is very similar to the instantiation of new objects in object-oriented programming.
dtkeden -s -c nThe syntax for running dtkeden as a client is as follows, where "-a" signifies that this is a client (agent) and "-h hostname" signifies that the client should connect to the server running on a computer system with name "hostname":
example: mischief> dtkeden -s -c 55
dtkeden -a -c n -h hostnameIn these examples, n refers to the communication channel at the server, an integer between 0 and 99. When a client wants to connect to a particular server, the channel number and the hostname of the server must be specified exactly. Currently, each client is allowed to connect to one server only. When connected to the specified server, a window requesting a login name opens at the client end. You can also execute a dtkeden server alone without clients.
example: cottage> dtkeden -a -c 55 -h mischief
When dtkeden is started, the superagent, acting in the role of an external observer, may need to specify a modelling mode of interaction for the whole system other than the default Normal Mode. In the current version, there are four modes serving different styles of modelling. In normal use, the modelling mode should be established at the beginning of interaction and not subsequently modified during a modelling session. (It is possible to change the mode during a modelling session.) To specify a modelling mode, you can click on the ôTypeö menu item and then select a sub-item from the following choice list. The term request is used to refer to a valid message, which typically consists of segments of tkeden input.
In this mode, the LSD Agent is activated to deal with the management
of access permission and propagation of change for each variable's definition.
Any request will be accepted by the server, subject to currently defined
privileges associated with an agent. If the request is to (re)define
an observable, the LSD Agent will immediately provide this service.
This mode is good for hierarchical modelling environments where the relationships
between agents are known. To set up the privileges, the LSD
Notation supported in dtkeden should be used.
This mode allows the superagent to directly interfere with the interactions
between agents, or between each client and the server. Before being
serviced, each request is displayed on the server's input window.
The superagent, like a God, then has discretion over how the suspended request is processed, eg. to perform ôwhat-if?ö experiments or to issue an unexpected request. This mode is of particular interest for modelling the phenomena
of the real world where many-to-many interactions are the norm, and singular conditions requires the intervention of a God-like superagent.
This mode provides a broadcasting function by which any request
sent to the server will be propagated to all other clients. This
supplies an open environment for multi-agent modelling, such as is needed for a multi-user game.
In the private mode, each client has a "private" communication channel to the server. In contrast to the broadcast mode, no request will be propagated to the other clients. This is an individual modelling mode suitable for many-to-one environments.
The current state of the server's interaction modes can be examined and changed via commands in the dtkeden input window. For the management of agents' privileges in "Normal Mode", the LSD Agent in dtkeden creates and maintains three lists for each observable. For example, if the list of oracle privileges for an observable mmm is [xxx, yyy], then both agents xxx and yyy have the oracle privilege for the observable mmm. You can see these three lists by using the function symboldetail("mmm"), which returns the privilege details associated with observable mmm. The format of the EDEN list returned is:
[mmm,type,defn,l1,l2,[oracle_agents],[handle_agents],[state_agents]]For any observable in any state, an oracle_agents list, handle_agents list or state_agents list is either:example:
writeln(symboldetail("a"));
[a,formula,b+c;,[b,c],[],[EVERYONE],[sun,carters],[EVERYONE]]
EveryOneAllowed = TRUE;In this case, a default agent name called "EVERYONE" will be set for every new definition and the LSD Agent will automatically grant every agent open access privileges to redefine and observe all newly created observables.
EveryOneAllowed = FALSE;In this case, no agent has any access privileges to observe or redefine the observable.
The default value for EveryOneAllowed is TRUE. It can be changed through the LSD Notation or by special functions. More details will be given later in this document.
The superagent can determine the nature of synchronised communication between the server and the underlying EDEN, DoNaLD and SCOUT interpreters by setting the value of the system variable ôsynchronisedö. When synchronisation is set, dtkeden waits until the underlying processing is finished after sending a redefinition before presenting the next redefinition. When synchronisation is not set, redefinitions are sent to the underlying tools without any check and may not be processed.
synchronised = 1; ----> synchronised (the default)This system variable value should be set with caution as it can give rise to infinite waiting.
synchronised = 0; ----> not synchronised
Having entered an agent name, a dtkeden client input window
is displayed, as shown directly below. This window contains the same
menu items as tkeden with the addition of a "Send" item.
After entering an agent name, you are connecting to the specified server and allowed to do what you can do in tkeden. You can also send a definitive script to the server by clicking "Send" menu item. This operation forces dtkeden to both accept scripts and send them to the server as well. The way which a transmitted script is handled by the server depends on the interactive mode of the server as chosen by the superagent.
sendClient("clientname", "script");Here, a clientname is the clientÆs agent name entered when the client initiated connection.
example: sendClient("client1", "a is b+c;");
There are two ways to send the server scripts entered into the input window. One is to click the ôSendö item on the menu bar. It will inform dtkeden to accept the sent script for itself and send the server the same script. Another way to do it is to use the ôsendServerö command, which has the following syntax:
You can use the ôsendClientö command to send a specific client scripts.
sendClient("clientName",
"scripts");
example: sendClient("client1",
"a is b+c;");
In some cases, you may want to know the current value of a variable (or an observable) at the server end, e.g. to see if it is different from the current value at the client. Using the "queryObs" command, the value of a server's variable can be shown in the history window of the client.
queryObs("observableName");
example: queryObs("x");
If you want to renew an observableÆs definition or value to be the same as the latest one at the server end, the "renewObs" command can be used.
renewObs("observableName");
example: renewObs("x");
Given the example command above, dtkeden at the client end will receive the latest definition or value of the observable "x" at the server, e.g. "x is y-z;".
agent agentNameThe agent statement associates all the following statements with agent agentName. The oracle, handle and state observable lists contain observable names associated with the privileges to access the observables by agentName. The following example illustrates how to use the LSD notation.
oracle observableName[, observableName]
handle observableName[, observableName]
state observableName[, observableName]
remove LSDType observableName[, observableName]
%lsd <----- declare the use of LSD notationYou can choose the "View LSD Description" sub item in the pop down menu of the ôViewö item of the server's input window menu to check your LSD description.agent xxx <----- declare the agent name
oracle a, b, c <----- add agent xxx the oracle agency for observables a, b, c.
handle a, m <----- add agent xxx the handle agency on observables a, m.
remove oracle b <----- remove from agent xxx the oracle agency for observable b.agent yyy <----- declare a new agent name
oracle m, c <----- add agent yyy the oracle agency for observables m, c.
handle b, m <----- add agent yyy the handle agency for observables b, m.%eden <----- back to EDEN
There is another way to configure the behavior of the LSD Agent. You can dynamically manage the access privilege of an agent by commands "addAgency", "removeAgency" and "checkAgency". Their syntax as follows:
addAgency("agentName", "LSDType", "observableName");In these syntax descriptions, LSDType is one of three basic three supported keywords in the LSD Notation: oracle, handle and state. The first two commands are used as if EDEN procedures and the last one is a function returning a value of TRUE or FALSE. If TRUE (actually an integer of value 1) is returned by the command checkAgency, it means that the specified agent agentName has the identified privilege LSDType for the specified observable observableName. If the agent does not have this privilege, a FALSE (0) value is returned.
example: addAgency("yyy", "oracle", "b");removeAgency("agentName", "LSDType", "observableName");
example: removeAgency("yyy", "handle", "m");checkAgency("agentName", "LSDType", "observableName");
example: checkAgency("xxx", "handle", "w");
The symbols which may be used will now be explained in their pairs, where the ">~" symbol in (5) is for "Normal Mode" interaction and symbols (1) to (4) should be used in the other four modes of interaction.
This symbol requires an agent's name will follow it and switches to a new context associated with this name. This context will persist until the invocation of a new virtual agent or a reset to the root context with the ">>" symbol (on its own). For example, the script
>>sun
x is y + z;
>>
will be represented as follows in the root context:
sun_x is sun_y + sun_z;
The protocol used by this symbol is similar to ">>" except that the agent's name is appended to the end of each observable name. Therefore, the last example will be represented in the root context as:
x_sun is y_sun + z_sun;
This symbol is used to denote that the string that follows corresponds to the name of a variable that contains an agent's name, so dtkeden will set up a context associated with this agent's name rather than the variable name. For example, if we have the following code
name = "button1";
>< name
a is b - c;
>>
then this will be represented in the root context as:
button1_a is button1_b
- button1_c;
In the same way that (2) is related to (1), in this case dtkeden
will use the protocol from (3) and append this agent's name given in a
named variable to the end of each observable.
This symbol does not cause dtkeden to change the current context to the specified agent name. In this case, the (re)definitions that follow between the pair of symbols associate the named agent. The LSD Agent checks that the named agent has appropriate access privileges to modify these variables in the root context. Typically this is used in the "Normal Mode" where access privileges need to be checked by the LSD Agent in order to ensure the integrity of the specified agency over the current observables. For example, the script
>~ sun
x is y + z;
>>
will be represented in the root context as:
x is y + z;
If this example is in the "Normal Mode" of interaction, The LSD Agent will check if the agent named sun has the access privilege handle on the observable x.
>>sunwill be represented in the root context as:
x is y + ~z;
>>
sun_x is sun_y + z;In the current version of dtkeden, virtual agents can be applied to the EDEN, DoNaLD and SCOUT notations.
The first program:
><buttonID
%scout
display buttonWin;
window button;
integer buttonPosX, buttonPosY;
string buttonLabel;
button = {
frame : ([{buttonPosX, buttonPosY}, {buttonPosX +
(~buttonWidth), buttonPosY + (~buttonLength)}]),
string : buttonLabel,
relief : "raised",
border : 2,
bgcolor : "blue",
fgcolor : "white",
alignment : CENTRE,
sensitive : ON
};
buttonWin = <button>;
~buttonsScreen &= buttonWin;
%eden
buttonLabel = ~buttonID;
buttonPosX = ~buttonsScreenPosX + (~buttonNo % ~maxColumns) * (~buttonWidth);
buttonPosY = ~buttonsScreenPosY + (~buttonNo/~maxColumns) * (~buttonLength);
>>
The second program shows how to use the command include to instantiate a button from the button panel in the first program.
The second program:
%scout
display buttonsScreen;
integer buttonsScreenPosX, buttonsScreenPosY;
integer buttonLength, buttonWidth;
screen = buttonsScreen;
%eden
proc init {
auto i, j;
for (i=0; i<maxRows; i++) {
for (j=0; j<maxColumns; j++) {
buttonID = "w" // str(i)
// "w"// str(j); /* specify button name */
buttonNo = i * maxColumns
+ j;
include("button.panel");
/* instantiate a button */
eager();
}
}
}
maxColumns = 15;
maxRows = 10;
buttonsScreenPosX = 100;
buttonsScreenPosY = 100;
buttonLength = 30;
buttonWidth = 30;
init();
To run these two programs, the first program needs to be stored in a file called "button.panel" in the directory where dtkeden was started from. Then it is necessary to include the second program into the input window of dtkeden and click the "Accept" menu item.