This document gives a full description of SOML version 0.9, the markup language that is to be used as a protocol on the World-Wide-Mind. The protocol described uses an XML-like language that falls short of full strength XML for reasons discussed elsewhere. Several advanced features built into the protocol include service description and discovery, similar to mechanisms employed in web services, and tunnelling, a system which allows non-standard messages to be exchanged between entities involved in a run on the World-Wide-Mind.
This document provides a full description of the first specification of a protocol for the World-Wide-Mind [Humphrys, 2001, Humphrys and O'Leary, 2002b, w2mind.org, 2002]. The protocol is named SOML, standing for the Society of Mind Markup Language, as its purpose is to allow various sub minds collaborate using the World Wide Web in order to create large whole minds, and also to allow these minds to interact with the bodies which they control. Using the web large minds can be build using components developed completely independently of eachother, and in turn these minds can interact with an environment (or world) that was developed independently by another researcher. In order for such an architecture to be possible all the various communicating entities must understand the same messages, and respond in a standard fashion to these messages (in the same way as the HTTP protocol operates). This document lists a set of messages which satisifes a minimal set of requirements for such a protocol, yet still allows researchers involved in the project a large degree of freedom to extend and tailor the protocol to their own requirements. The protocol messages are all carried over HTTP, and the entities they communicate with receive the messages through CGI or equivalent. For this reason the online entities (servers) can be referred to as web services, but in order to distinguish them from larger efforts involving SOAP, UDDI, WSDL etc. we refer to these services as Lightweight Web Services. The messages are constructed using an XML-like language, but not strict XML, for reasons discussed elsewhere [Humphrys and O'Leary, 2002a].
The protocol is comprised of six core message pairs (request response), each of which will be discussed in turn below. One of these message pairs (getprofile) is significantly differnet from the others to warrant a more detailed description, so this will be left until the other five messages are described. Essentially, the getprofile response contains a description of the service provided by the world or mind which it is a part of. This description of the service lists all the arguments expected with each of the five core messages (for example the number of layers an artificial neural network should have, if the mind being described is an implementation of an ANN), as well as any additional messages that are supported by the service outside the core set (for example, the neural network implementation may support a message which returns the current weights).
The five other core messages are
newrungetstategetactiontakeactionendrunA run would then involve the following sequence...
newrun request sent to world. World returns a newrun response containing a runid for the specific run that has been started in the world.newrun request sent to mind. Mind returns a newrun response containing a runid for the specific run that has been started in the mind.getstate request sent to world. World returns a getstate response containing the state of the world.getaction request sent to mind. The request includes the state that was returned with the getstate response. Mind returns a getaction response containing the action decided upon based on the state of the world.takeaction request sent to world. The request includes the action that was returned with the getaction response. World returns a takeaction response containing the new state of the world.endrun request sent to world. World ends the run, and returns response.endrun request sent to mind. Mind ends the run, and returns response.takeaction in a world server) with an endrun response instead of a takeaction response, then this is an indication to the client that the world server has ended the run itself (perhaps because the algorithm has ended). It is then up to the client to end the run in the other entity.
The run is controlled by a piece of client software, the first implementation of which is a Java applet, and is described elsewhere [O'Leary, 2002].
All messages have the following form (excluding line numbers!)
1. <soml version="0.9"> 2. <response type="getaction" runid="123456" status="1001" statustext="This is the message"> 3. ... 4. </response> 5. </soml>All messages must begin with line 1 above. SOML is the name of the protocol, and the version number is the version of the protocol being used, the current version being 0.9.
The second line of all messages must have the same form as the second line in the message above.
request or response, as all messages are part of a pair, so a newrun request would be responded to by a service using a newrun response.type is the name of the message, this will typically be one of the six types that form the core of SOML, but could be another type, specific to a particular service.newrun request, and all subsequent requests. If it is contained in any response other than a newrun it will be ingored, as it will if it is contained in a request that does not require a run to have started (newrun request and getprofile request)statustext can also form part of the line, in order to provide more information about the status.
| ||||||||||||||||||||||||||||||||||||||
| Table 1. Response status codes |
A parameter is a value that is passed between entities (client to server or vice versa) as part of the core SOML protocol. It has a very simple form as shown below...
1. <soml version="0.9"> 2. <request type="getaction" runid="123456"> 3. <param name="state"> 4. (0, 0, 0, 9, 7, 8, 2, 0, 4) 5. </param> 6. </request> 7. </soml>or
1. <soml version="0.9"> 2. <request type="getaction" runid="123456"> 3. <param name="state" value="(0, 0, 0, 9, 7, 8, 2, 0, 4)"/> 4. </request> 5. </soml>
A param is a simple name value pair, with the value as either an attribute or contained as a child. There are no restrictions on the form that the value can take. A list of all parameters that are contained in the requests and responses for the six core messages is given in the relevant sections below.
An argument is precisely the same as a parameter except it is not a part of the core protocol, but is instead specific to some particular entity, and is advertised in the profile of the service. For example, if a layers argument was required for a newrun it could be contained in the message as follows:
1. <soml version="0.9"> 2. <request type="newrun"> 3. <param name="otherparticipant"> 4. http://otherhost.com/world 5. </param> 6. <param name="username" value="ciaran oleary"/> 7. <param name="usercontact" value="info@w2mind.org"/> 8. <argument name="layers" value="3"/> 9. </request> 10.</soml>or
1. <soml version="0.9"> 2. <request type="newrun"> 3. <param name="otherparticipant"> 4. http://otherhost.com/world 5. </param> 6. <param name="username" value="ciaran oleary"/> 7. <param name="usercontact" value="info@w2mind.org"/> 8. <argument name="layers"> 9. 3 10. </argument> 11. </response> 12.</soml>
All messages except for the getprofile message are constructed using the tags introduced above. The getprofile is described in the next section.
The messages shown below outline how messages are constructed and should be used as templates. The case used in messages is relevant, with lowercase being preferred in ALL circumstances.
The purpose of the profile is to provide a description of a service. Every service should provide a profile, even if it is empty. Using the profile, the following two things can be described
The getprofile request is identical to any other type of request, and is shown below. No runid is required since a run need not be started in order to get the profile of a service.
1. <soml version="0.9"> 2. <request type="getprofile"> 3. </request> 4. </soml>
A getprofile response consists of a set of messagespec tags, optionally accompanied by the following five parameters...
homedesc: The URL of the homepage foe this servicename: The name of the service e.g. "Edmund ASM"modified: The date it was last modifiedcreated: The date it was createdauthor: The name/e-mail/url of the author
A messagespec describes an individual message supported by the service. The <messagespec> tag takes an attribute called type. The type is the name of the message. If this name is one of the code messages, then this messagespec is going to describe some additional arguments that are going to be supported by the service. If the name is not one of the core set of five, then it is describing a new messge supported by the service.
1. <soml version="0.9"> 2. <response type="getprofile"> 3. <messagespec type="newrun"> 4. .... 5. </messagespec> 6. <messagespec type="getweights"> 7. .... 8. </messagespec> 9. </response> 10.</soml>
In the message above, the messagespec for newrun will describe the additional arguments that are supported by this service, for its newrun core request. The messagespec for getweights will describe the fact that this service supports a message called getweights as well as the other core messages.
The contents if a messagespec is always the following...
argspecsdescription is a natural language description of the message, and the arguments it expects. There is one argspec for each argument the message supports.
1. <soml version="0.9"> 2. <response type="getprofile"> 3. <param name="author" value="ciaran oleary"/> 4. <messagespec type="getweights"> 5. <description> 6. This message will return the weights of the network, 7. if provided with a boolean value indicating if 8. floating point or integer values are wanted. 9. </description> 10. <argspec name="usefloat"> 11. .... 12. </argspec> 13. <argspec name="weigths"> 14. .... 15. </argspec> 16. </messagespec> 17. </response> 18.</soml>
The format of an argspec is as follows. It takes four attributes:
direction: if this is set to in that means the argument forms a part of the request, if this is set to out that means the argument forms a part of the responsename: the name of the argumentdefault: the default value for the argument, if the user fails to supply onewrapped: if set to true the value selected by the user will be wrapped as a child of the argument tag, otherwise, it will be set as an attribute of the argument tag (see section on arguments above).alwayssend: if set to true the value of this argument is always sent in a message. Otherwise, the value is only sent by the client if it has been changed from the default.argspec tags is considered a natural language description of the argument.
1. <soml version="0.9"> 2. <response type="getprofile"> 3. <param name="author" value="ciaran oleary"/> 4. <messagespec type="getweights"> 5. <description> 6. This message will return the weights of the network, 7. if provided with a boolean value indicating if 8. floating point or integer values are wanted. 9. </description> 10. <argspec name="usefloat" direction="in" wrapped="false" default="true" alwayssend="true"> 11. If this is set to false then integer values are returned 12. </argspec> 13. <argspec name="weigths" direction="out" wrapped="true" default="" alwayssend="false"> 14. This message returns the weights being used as an array of numbers in square brackets 15. </argspec> 16. </messagespec> 17. </response> 18.</soml>
If the profile above was returned by a service, then the request shown below would be responded to by the response given with it...
1. <soml version="0.9"> 2. <request type="getweights"> 3. <argument name="usefloat" value="true"/> 4. </request> 5. </soml>
1. <soml version="0.9"> 2. <response type="getweights"> 3. <argument name="weights"> 4. [ 6.0, 7.6, 3.3, 5.8 ] 5. </argument> 6. </response> 7. </soml>
As the profile is static and not likely to change over time, it may be easier to write it once and leave it in a static page on the web server. If an author chooses to do this, then the getprofile response need only contain a single parameter called staticloc which contains the URL of the full profile, as shown below...
1. <soml version="0.9"> 2. <response type="getprofile"> 3. <param name="staticloc" value="http://hostname/worldprofile.soml"/> 4. </response> 5. </soml>
newrun
The newrun request takes three parameters, and the corresponding response takes one parameter. All these parameters are optional, although some client software may automatically generate values for these parameters.
The parameters in the request are as follows:
otherparticipant: The URL of the other participant in the run, i.e. if this newrun is being sent to the world, then this value is the URL of the mind and vice versa. The server may need to use this in order to find out about the capabilities of the other server, but will not be able to interact with it fully, as it will not be aware of the runid in the other server, therefore all communication relevant to this run will have to be tunnelled through the client (see the section below on tunnelling).username: The name of the user starting this run, this is supplied as it may be needed for a leaderboard.usercontact: The url/e-mail of the user starting this run, this is supplied as it may also be needed for a leaderboard.newrun request (excluding any arguments) is shown below. Note that the runid is not included in the request.
1. <soml version="0.9"> 2. <request type="newrun"> 3. <param name="otherparticipant"> 4. http://mindurl/mind 5. </param> 6. <param name="username" value="ciaran"/> 7. <param name="usercontact" value="info@w2mind.org"/> 8. </request> 9. </soml>
The parameter in the response is:
topscore: Typically only used for a world server, the top score may be returned and shown to the user in the client window. The takeaction responses will include the current score so the user can be informed of how well it is doing.newrun response (excluding any arguments) is shown below. Note that the runid has just been generated and is contained in the response. This will be communicated with all subsequent requests.
1. <soml version="0.9"> 2. <response type="newrun" runid="123456" status="0001" statustext="New Run Started"> 3. <param name="topscore" value="100"/> 4. </response> 5. </soml>
getstate
The getstate request takes no parameters, but must contain the runid returned as part of the newrun response. This request is only ever sent to world servers, and its function is to return a representation of the state of the world.
A full getstate request (excluding any arguments) is shown below.
1. <soml version="0.9"> 2. <request type="getstate" runid="123456"> 3. </request> 4. </soml>
The parameters in the response is:
state: The state of the world. There is no set of rules determining the form this representation of state should take. It can be in another markup language, natural language or any other form.currentscore: The current score being achieved in the world. This parameter is also returned with the takeaction response.getstate response (excluding any arguments) is shown below. Note that the runid need not be included.
1. <soml version="0.9">
2. <response type="getstate" status="0001" statustext="State included">
3. <param name="state">
4. { 100, 23, 65, 78, 239, 84 }
5. </param>
6. <param name="currentscore" value="10"/>
7. </response>
8. </soml>
getaction
The getaction request takes one parameter, and must also contain the runid returned as part of the newrun response. This request is only ever sent to mind servers, and its function is to return a representation of the action decided upon based on the state of the world passed to it.
The parameter in the request is:
state: The state of the world obtained using the getstate or takeaction responses. getaction request (excluding any arguments) is shown below.
1. <soml version="0.9">
2. <request type="getaction" runid="123456">
3. <param name="state">
4. { 100, 23, 65, 78, 239, 84 }
5. </param>
6. </request>
7. </soml>
The parameters in the response is:
action: The action to take in the world. There is no set of rules determining the form this representation of action should take. It can be in another markup language, natural language or any other form.getstate response (excluding any arguments) is shown below. Note that the runid need not be included.
1. <soml version="0.9"> 2. <response type="getaction" status="0001" statustext="Action included"> 3. <param name="action"> 4. LOOK_LEFT 5. </param> 6. </response> 7. </soml>
takeaction
The takeaction request takes one parameter, and must also contain the runid returned as part of the newrun response. This request is only ever sent to world servers, and its function is to instruct the server to execute the action sent to it, and then return the new state of the world, and the updated score.
The parameter in the request is:
action: The action to be executed in the world, as obtained using the getaction request to the mind server. takeaction request (excluding any arguments) is shown below.
1. <soml version="0.9"> 2. <request type="takeaction" runid="123456"> 3. <param name="action"> 4. LOOK_LEFT 5. </param> 6. </request> 7. </soml>
The parameters in the response is:
state: The updated state of the world, as in the getstate response above.currentscore: The current score being achieved in the world. This parameter is also returned with the getstate response.takeaction response (excluding any arguments) is shown below. Note that the runid need not be included.
1. <soml version="0.9">
2. <response type="takeaction" status="0001" statustext="Action executed, state included">
3. <param name="state">
4. { 100, 23, 65, 78, 239, 84 }
5. </param>
6. <param name="currentscore" value="12"/>
7. </response>
8. </soml>
endrun
The endrun request takes no parameters, but must contain the runid returned as part of the newrun response. This request can be sent to world or mind servers, and its function is to instruct the server end the run corresponding to the runid passed in.
A full endrun request (excluding any arguments) is shown below.
1. <soml version="0.9"> 2. <request type="endrun" runid="123456"> 3. </request> 4. </soml>
There are no parameters in the response. A full endrun response (excluding any arguments) is shown below. Note that the runid need not be included.
1. <soml version="0.9"> 2. <response type="endrun" status="0001" statustext="Run ended"> 3. </response> 4. </soml>
Oftentimes it may be necessary for the world server to talk to the mind server or vice versa. It is possible for them to do this directly, without going through the client since the newrun message contains the URL of the otherparticipant. However, the server does not have the runid being used in the other server. This is done so as to prevent it contacting to server directly to execute an action, as the client should be informed of this, and it should then pass the message on. It is fine, however, for the servers to examine, say, eachother's profiles, as this does not require a runid, and will not affect the run.
Tunnelling refers to a situation where a server responds to a request with another request, instead of a response. If the client receives a request in response to a request, it assumes that the server wishes for this request to be forwarded on to the other server, so the relevant runid is added to it, and it is sent to the other server. The response that is received from the other server, os in turn returned to the original server, who then sends the response desired for the original request.
This process does not affect the development of the protocol, as it is really just an implementation matter for the client, and as such it is again treated in the description of the client software [O'Leary, 2002].
This document has described the protocol SOML 0.9 as it will be used on the World-Wide-Mind. Examples of all messages are given, with special attention paid to the process of description and discovery. The protocol has intentionally been kept simple, with mechjanisms built in for extensibility by a server author.