[Next] [Previous] [Up] [Top]

chapitre 6 Le décideur, son organisation et son environnement

6-3.2 Etudes de cas: Le langage "Ross" de Rand


Depuis le début des années quatre-vingt, un groupe de recherche de la Rand Corporation dirigé par Phil Klar a cherché à appliquer à la simulation les techniques de l'intelligence artificielle et surtout celles des systèmes expert. Leurs travaux sur la "simulation à bases de connaissances" (angl.: knowledge-based simulation) a donné comme premier produit Ross: le "Rand object oriented simulation language" (cf. MacArthur 1986). Ross est un langage de simulation "objets" plus particuilièrement destiné à la simulation des interactions dans un système d'acteurs. Faire un modèle Ross consiste essentiellement à définir des objets du domaine à modéliser, leurs attributs et leurs règles de comportement. La syntaxe de Ross ressemble un peu près à un anglais très simple et elle peut donc être comprise par quelqu'un qui ne possède pas de connaissances en informatique ou en intelligence artificielle. Cette volonté de rester près du langage de l'utilisateur et des experts humains reflète une philosophie de la Rand (cf. Klahr (1986b). Une première version de ce langage existait déjà en 1982.

Ross a surtout été utilisé dans le domaine militaire comme pour le système SWIRL (Simulating War in the Ross Language). Il s'agissait là de la simulation stratégique d'une bataille aérienne*1. Plus tard, grâce au système TWIRL (Tactical Warfare in the Ross Language, cf. Klahr 1986) Ross a été complété et stabilisé en quelque sorte (cf. MacArthur 1986). Le but de TWIRL était de simuler un engagement entre deux forces et de permettre le développement et la critique de tactiques militaires. Plus précisément, il s'agit de travailler avec le scénario d'une division rouge qui veut traverser une rivière défendue par une division bleue, et de l'utiliser comme cas test pour explorer des questions de commandement, de contrôle, de contre-mesures de communication, ainsi que de guerre et de combat électronique. Le type de scénario modélisé possède des propriétés structurelles similaires à celles des échanges dans une organisation. En effet, dans les deux cas, il s'agit d'un système d'acteurs qui échangent des messages. Ces messages seront traités par chaque acteur selon une "méthode" appropriée et peuvent produire d'autres messages. Le tout se déroule dans une perspective chronologique et causale.

Ross était le premier produit du projet KBSim ("Knowledge-Based Simulation"). KBSim possède maintenant une vocation plus large. Il s'agit en fait de réaliser la synergie entre les langages de simulation orientés objets, les coquilles à base de règles, la programmation logique, les inférences automatiques et les graphiques interactifs pour créer un nouveau type d'environnement de simulation (cf. Rothenberg 89:v). Un environnement plus large de simulation à bases de connaissances ("knowledge based simulation") comprendra également un moteur d'inférence ainsi qu'une base de données intelligente comme c'est le cas de Simkit*2 .

Ross est aujourd'hui un langage assez stabilisé dont il existe plusieurs variantes. Nous avons d'abord testé un prototype de Ross qui tourne sous TI-PC Scheme avec un PC Compatible. Il s'agit d'une version assez réduite que nous avons élargie et améliorée un peu. Toutefois, au plan conceptuel de la modélisation il possède plus ou moins les mêmes fonctionnalités que les grandes versions mais il ne dispose pas d'interface graphique, ni d'outils pour le "knowledge engineering" ou l'inspection du système. Plus récemment une version similaire appelée "Gnu-Ross" à été mise à disposition de la communauté. Elle tourne sous toutes les implémentations de Common-Lisp.

Objets, messages et comportements dans Ross

La structure d'un modèle de simulation objets se définit avec des objets, des messages entre objets et des comportements (cf. McArthur 1986: 74ff). La programmation d'un tel modèle se rapproche de près de la façon dont on décrit intuitivement les objets et les processus d'un système dynamique tel que l'on peut l'observer. En effet, beaucoup de systèmes sont d'abord décrits en termes de leur composantes séparées. Une composante d'un système peut en effet se définir par ses attributs et ses comportements possibles. Nous donnerons ici une introduction sommaire à Gnu-Ross (une version "domaine publique").

Le comportement du système peut se définir comme l'échange d'informations entre les objets. Les interactions entres objets ROSS se font grâce à une technique appelée "message passing" en informatique. La syntaxe pour passer un message à un objet est la suivante*3:

				(ask <objet> <message>)
ou le synonyme:				(tell <objet> <message>) 
Un objet Ross peut représenter un acteur (humain ou collectif) ou n'importe quel autre type d'objet. Un message représente n'importe quelle liste de mots que l'objet est capable de comprendre, par exemple:

(tell FirstInstance make decision
      with case acquisition-1 by demander Muller)
Notez que l'on peut très bien utiliser n'importe quel mot français à condition que l'objet receveur puisse les comprendre. Lorsqu'un objet reçoit un message, il doit être capable de le comprendre. Le modéliseur doit donc spécifier un comportement-type dont la structure d'activation, c'est-à-dire le chablon correspond (angl.:match) au message, et dont les actions représentent une réponse adéquate. La syntaxe pour définir le comportement d'objet est la suivante:

(ask <objet> when receiving <structure d'activation> <actions>) 
On demande donc à un acteur de "se" définir un comportement en lui envoyant un message "when receiving .... ". Cet exemple illustre bien l'usage très général du "message passing" au delà de la simulation proprement dite. La structure d'activation est une liste de symboles qui peut contenir des variables, comme par exemple:

(make decision with case > acquisition by demander > demander) 
Les symboles précédés par ">" sont des variables. Un message comme "make decision with ...." correspond à cette structure et peut donc activer un comportement. La notion de variable dans une structure d'activation est très importante. En effet, c'est grâce à ce mécanisme que le système peut opérer avec une certaine flexibilité. Ces variables peuvent ensuite être utilisées dans le code du comportement. (c'est-à-dire elles seront remplacées par les valeurs dans le message). Dans notre exemple, "acquisition-1" est la valeur de "acquisition" et "Muller" est la valeur de "demander". La variable myself possède un statut spécial. Il s'agit ici d'une autoréférence à l'objet. On l'utilise par exemple pour envoyer un message à soi-même ou pour envoyer l'identité de l'objet à un autre objet. Les actions du comportement sont déjà plus difficiles à formuler. Dans un cas simple, un corps d'action simple consiste simplement en une suite de messages que l'on envoie à d'autres objets. Voici un exemple simple qui définit un comportement appelé "commander". Lorsqu'il reçoit le message d'envoyer un objet à un endroit, il envoie à cet objet le message d'y aller.

(ask commander when receiving 
		(send > moving-object to > place) 
		(ask ! myself 
			tell ! moving-object go to > place) 
Examinons un exemple plus difficile: dans ces messages (et en règle générale dans leur corps d'actions), on distingue entre expressions non-évaluées et évaluées. Une expression est en règle générale un simple symbole ou une liste représentant un message dont on veut utiliser la "réponse". Une expression non-évaluée doit être interprétée textuellement, tandis qu'une expression évaluée retourne une valeur utilisée par la suite. Dans Ross, toute expression précédée par un "!" doit être évaluée (de la même façon qu'une valeur remplace le nom d'une variable). Les autres sont interprétées textuellement. On emploie le "!" surtout pour pouvoir utiliser la valeur des variables correspondantes (angl.: "match") à la structure d'activation et pour utiliser le résultat de l'envoi d'un message. Pour pouvoir envoyer un message à l'objet lui-même il faut utiliser la variable "! myself". Voici un exemple tiré de McArthur (86:75):

(send > moving-object object guided by > guider to > whom) 
... et un comportement qui lui correspond: 
(ask fighter-base when receiving 
          (send > fighter guided by > gci to > penetrator) 
    (ask ! myself 
           schedule after 
           ! ( ask myself recall your scramble-delay) seconds 
           tell ! fighter chase ! penetrator guided by ! gci) 
    (ask ! myself add ! fighter to your list of fighters-scrambled) 
    (ask ! myself remove ! fighter from your list of fighters-available)) 
Ce comportement s'active donc grâce à un message du type "(send > fighter guided by > gci to > penetrator)" et a pour résultat 3 comportements internes (les 3 "ask ! myself"). Le premier comportement contient deux autres, dont un comportement externe qui lance au bout de quelques secondes un "tell ! fighter chase ! penetrator guided by ! gci" pour instruire un avion chasseur. Ainsi, un comportement modélise donc les façons dont un objet peut répondre à des "inputs" (perceptions, informations, forces) dans le "monde" à modéliser. Ces comportements sont en règle générale spécifiés par rapport à un certain type d'objets. Il n'est donc pas nécessaire de faire ce travail pour chaque objet individuel dont on dispose. Dans un "corps" de comportement, une commande Ross commence par un "ask ...." ou par un "tell..." qui est un synonyme.

Ross possède en outre une série d'expressions spéciales entourées de parenthèses comme "(your ....)". Elles ont deux fonctions: (1) certaines rendent la lecture du code plus simple, il s'agit donc d'abréviations. Par exemple (your status) se traduit par (ask myself recall your status). Ce sont en quelque sorte des pronoms conceptuels. Dans Ross, l'utilisateur peut en définir lui-même, dans Gnu-Ross, il faut posséder quelques connaissances en programmation pour le faire. (2) Les autres abréviations sont des constructions de contrôle. Il s'agit là essentiellement de la création de variables temporaires, de conditionnels et de boucles. A la place de ces constructions fournies par Ross, il est bien sûr possible d'utiliser directement des constructions Lisp. Mais ces dernières sont moins claires pour un utilisateur qui ne sait pas programmer.

La hiérarchie des objets

Les objets dans Ross sont définis par rapport à une hiérarchie d'objets et ils sont créés à l'aide d'un mécanisme d'héritage. L'objet de base à partir duquel on crée tous les autres s'appelle (ici) "ross". Les autres versions de Ross suivent de près les conventions de création d'objets que l'on retrouve dans les langages orientés objet. C'est-à-dire, on fait la distinction entre objets génériques et instances. Dans PC et-GnuRoss, cette distinction n'existe pas pour des raisons de ressources, mais elle devrait être faite au plan conceptuel. On utilisera la convention suivant laquelle tous les objets individuels (les instances) sont définis ou bien par des noms propres ou bien en rajoutant un nombre au nom comme dans "demander-1". Chaque objet créé par un autre objet hérite des attributs et des comportements de l'objet qui le crée. Autrement dit, si l'objet "ross" (qui est l'objet-parent de tout le monde) connaît un comportement (comme "create ..."), tous les autres vont également posséder ce comportement. Ce mécanisme d'héritage est un des très grands avantages de la programmation objet. Il permet de définir chaque comportement et chaque attribut à un niveau conceptuel approprié tout en laissant la possibilité de définir des comportements spécialisés pour chaque objet si on le désire. Un attribut est une variable qui contient de l'information sur l'état interne d'un objet. Il s'agit en règle générale de caractéristiques symboliques ou numériques qui décrivent l'objet; par exemple des mémoires que l'on utilise pour stocker de l'information, ainsi que des "queues" que l'on utilise pour y mettre les choses à faire. La hiérarchie des classes d'objets devrait refléter les dépendances conceptuelles du type "super-concept/sous-concept" (angl.: "isa" hierarchies) entre les objets dans le monde observé. La hiérarchie des objets dans Ross n'est pas nécessairement celle d'un arbre. L'héritage multiple est permis.

Suivant la version de Ross que l'on utilise, il existe un ou plusieurs acteurs prédéfinis qui possèdent les comportements de base

dont on a besoin pour une simulation. Souvenons-nous que chaque comportement qui est demandé à un acteur par le biais de "ask" (ou de "tell" qui est un synonyme) doit être défini soit par le programme Ross soit par le modéliseur. Gnu-Ross fournit trois acteurs de base à partir desquels on définit les acteurs du modèle: il s'agit de "ross", "clock" et "rng". "Clock" est la montre de simulation et "rng" est un simulateur de nombres aléatoires. L'objet "ross" est l'objet source qui possède une quarantaine de comportements de base, dont nous montrons les plus importants dans la figure 6-4
. Il est tout à fait possible de rajouter des comportements pour l'objet "ross". Etant donné que le comportement "when receiving ..." lui appartient, il n'y pas de problèmes. Voici l'utilité de quelques comportements prédéfinis:

Toutes ces commandes permettent de gérer les flux de communication et d'action dans un système d'acteurs. Voici quelques lignes de code montrant comment ammorcer la modélisation d'un tel système:

;; Creation d'un acteur générique

(ask ross create an instance actor)

;; Creation d'une "Administration"

(ask actor create an instance Administration)

;; Creation d'une "base de données" de cas acceptables

(tell Administration remember (
				 ((Working Permit C) (RealEstateType appartment))
				 ((Working Permit B) (RealEstateType appartment))
				 ))

;; Procédure de décision
;; Lorsqu'un cas se trouve dans la base de données, l'autorisation est
;; accordée, sinon elle est refusée.

(ask Administration when receiving
     (make decision with case > case by demander > demander)
     (if (ask !myself recall if any items match !case)
	 (tell !demander remember (Authorization granted))
       (tell !demander remember (Authorization refused))
       ))


;; Simulation d'un "cas"

(ask actor create an instance Muller)

(tell Administration make decision
      with case ((Working Permit C) (RealEstateType appartment))
      by demander Muller)

Critique et discussion

La critique principale que l'on peut adresser à des langages de type Ross, c'est que le modéliseur doit prévoir et programmer un certain nombre d'actions qui sont inintéressantes au plan conceptuel. Il s'agit d'un problème découlant du phénomène appelé le "frame problem" ou plus largement des "data consistency issues" en intelligence artificielle. Beaucoup d'objets possèdent un certain nombre d'attributs qui dépendent de l'évolution du temps. Cammarata (86:5) et al. leur donnent le nom d'attributs autonomes. En effet, dans nos essais avec ce langage, pour maîtriser ce phénomène, nous avons dû écrire plusieurs comportements Ross pour les objets en question qui leur sont envoyés régulièrement par la montre de simulation. Une autre solution aurait consisté à recalculer ces valeurs au moment où on veut les utiliser. Dans ce cas, tous les comportements ayant besoin d'une valeur auraient dû provoquer ce calcul. Un bon langage de simulation devrait permettre au modéliseur de déclarer des méthodes qui calculent un attribut au moment où quelqu'un a besoin de leur valeur. On parle dans ce cas d'un "if-needed demon". Un autre problème consiste en ce que Cammarata (86: 7) appelle les événements non-intentionnels (ou effets secondaires). Ces événements, comme par exemple le calcul de la distance entre deux objets par un de ces objets ne correspond pas à une action intentionnelle dans beaucoup de cas, mais on en a besoin pour déterminer par exemple si un rpv entre dans la zone active d'un radar. En principe, dans une simulation, on devrait seulement prévoir les activités que l'objet accomplit réellement. Ces calculs devraient être faits d'une façon asynchrone en fonction de l'évolution de certains attributs autonomes. Il est assez difficile de savoir comment interfacer un tel monde de simulation avec une interface graphique. Lorsque l'on possède beaucoup d'objets, il devient impossible d'afficher la position (ou d'autres informations) de chaque objet à chaque pas de simulation. Il faut chercher des méthodes moins gourmandes. Ces trois problèmes ont été résolus en partie dans des extensions du langage Ross utilisées chez Rand. Ross reste assez bien ancré dans la tradition de la simulation des événements discrets.

Objets, messages et comportements dans Ross
La hiérarchie des objets
Critique et discussion

THESE présentée par Daniel Schneider - 19 OCT 94

Generated with WebMaker