[There's a french version below]

Hello,
I am currently developing a multi agent system engine in Ocaml, and although a first version of this engine works really well, I have some difficulties to generalize the engine to any kind of agent. The difficulty comes from the organization, in particular strategy of typing that I chose.

My engine can animate agents - which are represented by objects - with a hierarchical finite state machine. In such an automaton, each state can contains a finite state automata that will be activated in this state.Thus, one can define different behaviors and sub behavior in the agent.

I'm not very good at schematic, but here is one, to illustrate:
http://imagepaste.nullnetwork.net/viewimage.php?id=3044


Transitions are suitable for SMA: they pass from internal conditions, but external events. It is evaluated on the agent, or the event using a Boolean function:

type ('agent' event) transition =
   Condition of (agent -> bool)
  | Event of ('event -> bool)
  | EventOr of ('event -> bool) * (' agent 'event) transition
  | EventAnd of ('event -> bool) * (' agent 'event) transition
  | EventXor of ('event -> bool) * (' agent 'event) transition
  | EventNot of ('event -> bool)
  | ConditionOr of (agent -> bool) * ('agent' event) transition
  | ConditionAnd of (agent -> bool) * ('agent' event) transition
  | ConditionXor of (agent -> bool) * ('agent' event) transition
  | ConditionNot of (agent -> bool);

We can define any Boolean equation to define a simple transition.

Now my code is organized as follows:

- Class  "state" manages the state and seeks what transition applies. Of course, what is in this class performed the functions (agent -> bool) or ('event -> bool) which involves the acquisition of the static type. Each state possesses all the possible transitions to other instance of "state".
- A class "directory" that allows you to associate each agent to a  identifier string, because the events are designed to be sent from the outside (HTTP or other). Typically, an event can be a command that the user sends to the controller.
- A class "masEvent" which can receive events from the outside, to identify agents which are involved by the event.
- A class "agent" that embeds all the state transition diagram of the agent. It was he who receives "emails" including a masEvent. His method "cycle" is used to start the process of moving (if applicable) to another state.


The objective:
my goal is to manage any kind of agent, which would ideally objects inheriting from "agent". These objects do not redefine methods, they just add new data and methods.
 If I am willing to rewrite everything as a module, I would like at least that the agents to remain objects in order to manage their mutable datas.

The problem:
It is very difficult to ensure that the "state" object knows all objects inheriting from "agent", but it is essential to ensure the compiler accepts it.

My current solution is to give two agents as generic type to state:
class ['typeAgent' objetDuJeu] state (myAgent 'typeAgent) = object (self)

 during its instantiation, but it is very inconvenient because it implies that we must do the same for objects and annaire masEvent:

class ['typeAgent, item] masEvent (directory) = object (self) ...
['TypeAgent, item] directory (myAgent, myObj) = object (self) ...

Indeed, "directory" must know all types inheriting from agents.
This solution isn't flexible and implies a lot of problems.

Solutions i though :
- Define all objects which inherits from "agent" as virtual and redefine true class which inherits really from these virtual class, it's very tricky...
- Rewrite state, masEvent, directory as module ?

My question is this: what I could choose smart strategy to ensure that "state" can easily manage any kind can be agents, with only constraints they inherit "agent"?

Thank you





Français :
Bonjour,
je suis en train de développer un moteur Système Multi Agent en Ocaml, et bien qu'une première version de ce moteur fonctionne très bien, j'ai quelques difficultés à le généraliser à toute sorte d'agent. Cette difficulté tient à l'organisation, à la stratégie de typage que j'ai choisi (et au fait que j'ai réellement découvert ocaml pendant son écriture :-) ).

Mon moteur permet d'animer des agents, qui sont matérialisés par des objets, avec un automate à état fini hiérarchique. Dans un tel automate, chaque état peut abriter un automate qui va s'activer lorsqu'on passe dans cet état. Ainsi imbriqués, on peut définir divers comportements et sous comportements de l'agent.

Je ne suis pas très bon pour les schémas, mais en voici un :
http://imagepaste.nullnetwork.net/viewimage.php?id=3044


Les transitions sont adapté à un SMA : elles se font à partir des conditions internes, mais aussi des évènements extérieur. On évalue sur l'agent, ou sur l'évènement une fonction rendant un booléen :

type ('agent, 'event) transition =
   Condition     of ('agent -> bool)
  | Event        of ('event  -> bool)
  | EventOr      of ('event -> bool) * ('agent,'event) transition
  | EventAnd     of ('event -> bool) * ('agent,'event) transition
  | EventXor     of ('event -> bool) * ('agent,'event) transition
  | EventNot     of ('event -> bool)
  | ConditionOr  of ('agent -> bool) * ('agent,'event) transition
  | ConditionAnd of ('agent -> bool) * ('agent,'event) transition
  | ConditionXor of ('agent -> bool) * ('agent,'event) transition
  | ConditionNot of ('agent -> bool);;

On peut ainsi définir n'importe quelle équation booléenne simple pour définir une transition.

Aujourd'hui mon code est organisé comme suit :

- Une classe "state" gère les état, et cherche quel  transition s'applique. Bien entendu, c'est dans cette classe qu'est exécuté les fonctions ('agent -> bool) ou ('event -> bool) qui implique d'avoir connaissance du type statique de chaque agents. Chaque state, possède l'ensemble des transitions possible vers d'autres instance de "state".
- Une classe annuaire qui permet d'associer chaque agent a un identifiant de type string, en effet les évènements sont conçus pour être envoyé depuis l'extérieur (requete http ou autre). Typiquement, un évènement peut être une commande que l'utilisateur envoie à l'automate.
- une classe "masEvent" qui permet de recevoir les évènements de l'extérieur et d'identifier les agents que l'évènement implique (l'évènement doit fournir les identifiants)
- Une classe "agent" qui embarque tout le schéma d'état transition de l'agent. C'est lui qui reçoit des "emails" comprenant un masEvent. Sa méthode "cycle" permet de lancer le processus de passage ( s'il y a lieu ) à un autre état.


L'objectif :
    mon objectif est de pouvoir gérer toute sorte d'agent, qui seraient dans l'idéal, des objets héritant de "agent". Ces objets ne redéfinissent pas de méthodes, ils ajoutent des données et des nouvelles méthodes.
 Si je suis prêt à tout réécrire sous forme de module, j'aimerai au moins que les agents restes des objets, afin de pouvoir gérer leur données mutables.

Le problème :
    Il est très difficile de faire en sorte que l'objet state connaisse TOUS les objets héritant de "agent", mais c'est indispensable pour que le compilateur l'accepte.

Ma solution actuelle consiste à donner 2 agents comme type générique à state :
class ['typeAgent, 'objetDuJeu] state (myagent :'typeAgent) = object (self)

 lors de son instanciation, mais c'est très peu pratique parces que cela implique que l'on doivent faire de même pour les objets annaire et masEvent :

class ['typeAgent,'objet] masEvent (annuaire ) = object (self) ...
['typeAgent,'objet]        _ANNUAIRE  (myAgent ,myObj ) = object (self) ...

En effet, annaire doit connaitre tous les types héritant de agents.

Cette solution est absolument pas flexible et pose beaucoup de problèmes.

Solutions auxquelles j'ai pensé :
- Définir une version "virtuelle" de chaque agents spécialisé censé hériter de "agent", afin que state les "connaissent" ?
- Transformer "state", "masEvent" et "annuaire" en module, mais pour quel apport ?


Ma question est donc la suivante : quelle stratégie intelligente je pourrais choisir pour faire en sorte que "state" puisse gérer aisément toute sorte possible d'agents, avec seules contraintes qu'ils héritent de "agent" ?

Merci



Regards,
Pierre-Alexandre

--
---------------------
https://twitter.com/#!/ontologiae/
http://linuxfr.org/users/montaigne