Open gallandarakhneorg opened 10 years ago
I have reserved the keyword "space" in the grammar in order to avoid any conflict with variable names when we really introduces the space definition. The SARL grammar contains only an empty space declaration that must be extended with the features we want to appear in a space definition.
Following the discussions of Friday 16, September 2016 on how to define interactions at the environment border/interface, in other words between application agents and agents in charge of environmental missions.
The support to describe an environmental interface is the Space that describes the existing methods that could be directly called by application agents and really implemented by environmental agents.
The same approach will be used to implement Physical Environment or Graphical User Interface shared by a collection of distributed agents.
No Artifacts in SARL, everything is Agent, an Artifact is just an object managed by an environmental agent. And a environmental agent is just an agent assuming some environmental missions defines and exhibits by a space.
space SmartHome {
def update() fires SmartHomeUpdate
capacity Camera{
def capture (int h, int w) fires Capture
}
}
The previous code will automatically generate 2 capacities (SmartHome and Camera) and corresponding skills
Environmental Agents (an agent responding to space methods):
Agent ACamera {
on Capture {
//Do something
}
}
Agent Home {
on SmartHomeUpdate {
//Do something
}
}
Non environmental agent, the client calling something provided by the environment through the space:
Agent HomeUser {
uses Camera, SmartHome
on Initialze {
register(new SmartHome) // the registration gives the skills associated to Camera and SmartHome capacities
List<UUID> envtAgents = SmartHome.findallAgentWithCapacities(Camera.class)
}
on MyEvent {
SmartHome.update() // send SmartHomeUpdate event to Home agent
}
on MySecondEvent {
Camera.capture(23,35) // send Capture event to ACamera agent
}
}
I have a concern regarding the names of the generated elements. Consider:
package smarthome
space SmartHome {
def update() fires SmartHomeUpdate
capacity Camera{
def capture (int h, int w) fires Capture
}
}
space Camera {
}
It will generate two capacities with the same name in the package.
The problem is coming from the fact that the Camera
in the space is defined inside SmartHome
.
We should use a clear naming scope.
The question is: should we use the nested naming convention coming from Java?
In other words, the generated capacities will be named: SmartHome
, SmartHome.Camera
and Camera
.
I'm not fully convinced but I don't see any other solution, since I think we should not use the mechanisms that adds the "Capacity" and "Space" strings of characters at the end of the names automatically. The names should stay unchanged from the developer point of view.
We may generate a dedicated sub-package per space. (In our example, we may also consider the user is breaking naming conventions)
Packages: smarthome.smarthome and smarthome.camera Each one containing its set of provided capacities.
I'm not convinced by the implicit generation of packages because the problem will be moved. Consider the case the developer has defined by hand the generated package, and he has put capacities inside. We developer will have compilation errors that be not "fun"
_EXAMPLE 1_
Space with a shared data structure among the network, but without event bus.
The shared
modifier marks a field that should be created with a distributed data structure.
It is assumed that the injection and the type validation will be done.
space BlackboardSpace {
shared var Map<Object, Object> content
capacity Blackboard {
def putData(key : Object, value : Object)
def readData : Map<Object, Object>
}
skill BlackBoardSkill implements Blackboard {
def putData(key : Object, value : Object) {
content.put(object, value)
}
def readData : Map<Object, Object> {
Collections.unmodifiableMap(content)
}
}
}
_EXAMPLE 2_
Externalization of the capacity/skill definitions outside the space definition in order to enable reuses.
space BlackboardSpace {
capacity Blackboard
skill BlackboardSkill
}
capacity Blackboard {
def putData(key : Object, value : Object)
def readData : Map<Object, Object>
}
skill BlackBoardSkill implements Blackboard {
def putData(key : Object, value : Object) {
}
def readData : Map<Object, Object> {
}
}
_EXAMPLE 3_
Definition of a space with a shared data-structure among the network, and with an event bus.
event BlackboardChange
space BlackboardSpace2 extends OpenEventSpace {
shared var Map<Object, Object> content
capacity Blackboard {
def putData(key : Object, value : Object) fires BlackboardChange
}
skill BlackBoardSkill implements Blackboard {
def putData(key : Object, value : Object) fires BlackboardChange {
content.put(object, value)
/** Caution: the agent emits the event, not the space */
emit(new BlackboardChange)
}
}
}
_EXAMPLE 4_
Space definition only with an event bus.
space BlackboardSpace3 extends OpenEventSpace {
capacity Blackboard {
def putData(key : Object, value : Object) fires BlackboardChange
}
skill BlackBoardSkill implements Blackboard {
def putData(key : Object, value : Object) fires BlackboardChange {
/** Caution: the agent emits the event, not the space */
emit(new BlackboardChange(key, value))
}
}
}
_EXAMPLE 5_
Tentative to define a space factory that should evolves to a space specification.
factory BlackboardFactory of Blackboard {
override create() {
super.create()
}
def create(Map<Object, Object> initialData) {
var spaceInstance = create
spaceInstance.content += initialData
spaceInstance
}
}
_EXAMPLE 6_
Definition of a space for interactions with a situated environment (for simulation).
Introduction of the default
keyword for capacities.
The default
keyword enables the agent to have implicit skill for a capacity. The better location for creating the default skill instance in the agent is in getSkill
in order to enable overriding of the default skill with a skill given by the developer with setSkill
. The default skill mechanism could be generalized.
event Perception {
var neightbors : List<Object>
}
event Influence {
var action : Object
}
space SituatedEnvironmentSpace extends OpenEventSpace {
capacity EnvironmentManager default EnvironmentManagerSkill {
def notifyPerceptions(perceptions : Map<UUID, List<Object>>) fires Perception
}
skill EnvironmentManagerSkill implements EnvironmentManager {
def install {
register(owner)
}
def uninstall {
unregister(owner)
}
def notifyPerceptions(perceptions : Map<UUID, List<Object>>) fires Perception {
perceptions.forEach [ val p = it; emit(new Perception => [ it.neightbors = p])
}
}
capacity Situable default SituableSkill {
def doAction(action : Object) fires Influence
}
skill SituableSkill implements Situable {
def install {
register(owner)
}
def uninstall {
unregister(owner)
}
def doAction(act : Object) fires Influence {
emit(new Influence => [ it.action = act])
}
}
}
space SmartHome {
var content : Map<Object, Object>
on MyEvent [Guard1] fires SmartHomeUpdate
on MySecondEvent [content.get(?) == ?] fires Capture
on SmartHomeUpdate [it.source == new Address(X) ] fires EventFromEnvt [EmitGuard/Scoping]
on SmartHomeUpdate [it.hasCapacity(TotoCapicity)] fires Event2FromEnvt [EmitGuard2]
on Capture [ReceiveGuard5] fires Event3FromEnvt [EmitGuard3], Event4FromEnvt [EmitGuard4]
def update() fires SmartHomeUpdate
capacity Camera{
def capture (int h, int w) fires Capture
}
[optional, espcially for other space that are not event-based]
skill CamSkill implement Camera {
def capture (int h, int w) fires Capture {
if content.get(?) == ? {....}
}
}
}
Agent ACamera {
on Capture {
//Do something
}
}
Agent Home {
on SmartHomeUpdate {
//Do something
}
}
Agent HomeUser {
uses Camera, SmartHome
on Initialize {
register(new SmartHome) // the registration gives the skills associated to Camera and SmartHome capacities
List<UUID> envtAgents = SmartHome.findallAgentWithCapacities(Camera.class)
}
on MyEvent {
SmartHome.update() // send SmartHomeUpdate event to Home agent
}
on MySecondEvent {
Camera.capture(23,35) // send Capture event to ACamera agent
}
}
HomeAgent will have a skill overloading the asEventListener methods of an agent to insert a filter validating the Guard1 before calling the on clause of the MyEvent event. This skill requires to rewrite the default Behaviors BIC or the overload of the internal Eventlistener to implement this filtering process.
The space must exhibit a description containing the protocol to enable search on behaviours, capacities validating this protocol.
myspace.getDescription() : InteractionDescription
NewBIC.getAgentWithCapacities(C1): List
NewBIC.getBehaviorsValidatingDescription(InteractionDescription): List<List<Class<? extends Behaviors>> a second when you need multiple behavior to implement the space description.
Agent, Behavior and Space will have InteractionDescription that are dynamically computed and could then be matched to inform an agent of the list of behaviors it should acquire to enter a space.
class InteractionDescription { /* kinds of norms that is statically specified by the space and could be refine dynamically (runtime) */
var in: Class<Event>
var out: Class<Event>
}
implies to update the semantic of fire to be propagated into the hierarchy of caller (until an on clause, like a throw statement for an exception)
Feature to consider for the space: transversal rule associated to the space that can limit the scope of certain event types.
A part of this work is under progress with @stefanotedeschi. It is focussing on the implementation of protocol with SARL. No work is ongoing on the SALR syntax yet.
Great. Please include me in the discussions. Happy to organize a call.
The specific works on protocols are in a separate project until we decide to include it in the main project: https://github.com/sarl/sarl-protocols
This project focuses on protocols only. We don't try to define the concept of space in all its possible dimensions.
To enable the developers to code in SARL as much as possible, it could be interesting to add a new keyword related to the space concept (the only concept that has no keyword in SARL):
With this keyword, we will be able to write:
The corresponding grammar rule is:
The implementation of a space may be done in Java since the developer will certainly extend a platform-dependent class.