8.2 Modele de cooperation de GDRev
8.2.3 Architecture et interactions des dierents agents respectant les
Pour exprimer une notion d'ordre, une premiere idee consiste a utiliser l'operateur de sequentialite \:" a la place de l'operateur de parallelisme \," dans le corps de la re-qu^ete. Malheureusement, une telle formulation conduirait tres souvent a une situation de blocage. En eet, l'execution de B1 : B2 conduit a un blocage notamment si B1 se bloque. Ainsi, si par exemple l'evaluation de certaines proprietes par un agent sont dans un etat de blocage, il s'ensuit que l'agent suivant n'est pas execute. Par conse-quent, l'emploi de l'operateur de sequentialite est valide seulement dans les situations ou le premier agent execute reussit a construire entierement et tout seul la gure.
En fait, pour exprimer l'ordre d'execution des agents il s'agit de faire en sorte que l'execution d'un agent soit declenchee par son predecesseur une fois que celui-ci a eectivement evalue l'ensemble3 des atomes de propriete decrivant la gure. Cette approche nous conduit au schema d'execution illustre par la gure 8.4.
Ce schema illustre le fait que l'agent lineaire relance ses buts en attente tant qu'il arrive a evaluer des contraintes. Une fois bloque, il (re)lance l'agent quadratique. Celui-ci relance l'agent lineaire s'il a su evaluer une contrainte, ou l'agent completion d'objets dans le cas contraire. D'une maniere similaire, l'agent completion d'objets relance l'agent lineaire s'il a su determiner une corde commune ou une mediatrice, ou l'agent intervalle sinon. Enn, l'agent intervalle relance l'agent lineaire s'il a su instancier une variable, ou conduit a un succes.
Pour formaliser un tel mecanisme, nous associons a chaque agent une liste pourvue d'un suxe libre( FreesLinpour l'agent lineaire, FreesQuad pour l'agent quadratique,
FreesCptObjs pour l'agent completion d'objets, FreesInt pour l'agent intervalle). Ces listes sont regroupees dans une liste Frees. Elles ont un double r^ole. Elles permettent: 1. de gerer le processus de resolution en bloquant un agent, ou les buts d'un agent, en attente d'informations supplementaires sur le suxe libre de la liste lui cor-respondant dans l'argument Frees. Pour ce faire nous avons deni le predicat
gelerAgent( Id, LProps, LObjs, Frees)ou l'argument Id est l'identicateur de l'agent a geler.
Liberer un agent revient a specier que la variable (le suxe libre) sur laquelle
3. Nous allons voir plus loin que ceci n'est pas tout a fait exact s'agissant des agents quadratique et completion d'objets.
8.2 Modele de cooperation de GDRev 151
Agent linéaire
Agent quadratique
Agent complétion d’objets
Agent intervalle
Fig. 8.4 { Schema de contr^ole des agents.
il est en attente d'informations supplementaires est une liste ayant au moins un element. Pour ce faire, nous avons deni le predicat libererAgent( Id, Frees) ou l'argument Id est l'identicateur de l'agent a liberer.
2. d'\espionner" l'ajout de contraintes au systeme de contraintes courant par un agent en examinant la valuation du dernier element de la liste lui correspon-dant. Si cet element est une variable, cela signie que l'agent correspondant n'a pas pose de contraintes. Si cet element est instancie a la valeur 1, alors l'agent correspondant a reussi a poser une contrainte.
Pour marquer qu'un agent a reussi a poser une contrainte, nous avons deni le predicat marquerTellContraintes( Id, Frees) ou l'argument Id est l'identica-teur de l'agent.
Pour determiner si un agent a (resp. n'a pas) reussi a poser une contrainte nous avons deni le predicattellContraintes( Id, Frees)(resp.nonTellContraintes( Id,
Frees)) ou l'argument Id est l'identicateur de l'agent \espionne".
Il reste le probleme de pouvoir determiner si un agent a eectivement evalue tous les atomes de la liste des proprietes, dans la mesure ou l'evaluation d'un atome et le parcours des atomes de la liste des proprietes se fait en parallele. Pour resoudre ce probleme, une idee consiste a comptabiliser pour chaque agent d'une part les proprietes qu'il a evaluees, et d'autre part le nombre de ses appels recursifs. Un agent peut ^etre libere par son predecesseur (cf gure 8.4) si le nombre des proprietes evaluees par ce dernier correspond au nombre de ses appels recursifs avec la condition supplementaire que la liste des proprietes a evaluer est reduite a un suxe libre. Une maniere de denir
152 Modele de cooperation
un compteur est de construire une liste pourvue d'un suxe libre et de considerer que le nombre d'elements de celle-ci correspond a la valeur du compteur deni. Ainsi, pour comptabiliser d'une part le nombre des proprietes evaluees par un agent et d'autre part le nombre de ses appels recursifs, on construit deux listes de ce type appelees respectivementIn et Out.
agentLin(LProps, LObjs, In, Out, Frees):: gureNonConstruite(LObjs):
free(LProps):
conditionLiberation(In, Out)! etablirBilanLin(LObjs, Frees) agentLin(LProps, LObjs, In, Out, Frees)::
(Prop, SProps)^ know(LProps): tell(LProps = [Propj SProps]): marquerListe(Out):
(
evaluerAtomeLin(Prop, LObjs, In, Frees), agentLin(SProps, LObjs, In, Out, Frees) ) etablirBilanLin(LObjs, Frees):: estFigureConstruite(LObjs): terminerProcessus(Frees)! stop etablirBilanLin(LObjs, Frees):: estFigureNonConstruite(LObjs): tellContraintes(lin, Frees): libererAgent(lin, Frees)! etablirBilanLin(LObjs, Frees) etablirBilanLin(LObjs, Frees):: estFigureNonConstruite(LObjs): nonTellContraintes(lin, Frees): libererAgent(quad, Frees)! etablirBilanQuad(LObjs, Frees)
Tab.8.6 { Structure generale de l'agent lineairesous contr^ole.
La formalisation de cette idee est donnee pour l'agent lineaire dans le tableau 8.6. Le predicat conditionLiberation(In, Out), donne dans le tableau 8.7, est vrai si et seulement si les listes pourvues d'un suxe libreIn et Out ont le m^eme nombre
d'ele-8.2 Modele de cooperation de GDRev 153
ments. Le predicat marquerListe(L), illustre par le tableau 8.8, est vrai si le suxe libre de la liste L est une liste ayant au moins un element instancie a 1. Le predi-cat estFigureConstruite(LObjs) est vrai si et seulement si tous les objets de la gure contenus dans la liste LObjs sont construits. Inversement, le predicat estFigureNon-Construite(LObjs) est vrai si et seulement si il existe au moins un objet de la gure qui ne soit pas construit. Enn, pour achever le processus de construction, nous conside-rons le predicatterminerProcessus(Frees) qui libere tous les processus en attente an d'assurer une terminaison sans processus en attente.
conditionLiberation(In, Out):: free(Out) !stop
conditionLiberation(In, Out)::
(SOut, SIn)^(know(Out), know(In)) ! tell(Out = [ jSOut], In = [ jSIn]) !
conditionLiberation(SIn, SOut)
Tab. 8.7 {Condition de liberation de l'agent successeur.
On peut remarquer que cette formulation a conduit a ajouter a la clause evaluerA-tomeLin d'une part un argument In, c'est-a-dire un argument permettant de comp-tabiliser le nombre d'atomes evalues, et d'autre part l'argument Frees, c'est-a-dire la liste des listes de contr^ole des agents an de (re)positionner en attente l'evaluation d'une contrainte pseudo-lineaire.
marquerListe(L):: free(L) ! tell(L = [1 j ])! stop marquerListe(L):: know(L) ! (SL)^ L = [1 j SL]! marquerListe(SL)
Tab. 8.8 { Clause marquerListe/1.
La formalisation du contr^ole de l'agent quadratique peut ^etre faite d'une maniere similaire a celle de l'agent lineaire. Toutefois, an de reduire le nombre des racines
154 Modele de cooperation
carrees calculees, il est bloque une fois qu'il a evalue une contrainte quadratique. Ceci est realise gr^ace aux predicats decrits dans le tableau 8.9.
agentQuad(LProps, LObjs, In, Out, Frees):: free(LProps) !
libererAgent(cptObjs, Frees)
agentQuad(LProps, LObjs, In, Out, Frees):: (Prop, SProps)^ know(LProps):
tell(LProps = [Propj SProps]): marquerListe(Out):
(
evaluerAtomeQuad(Prop, LObjs, In, Frees),
poursuivreAgentQuad(SProps, LObjs, In, Out, Frees) )
poursuivreAgentQuad(LProps, LObjs, In, Out, Frees):: conditionLiberation(In, Out):
tellContraintes(quad, Frees): (
libererAgent(lin, Frees),
gelerAgent(quad, LProps, LObjs, In, Out, Frees) )
poursuivreAgentQuad(LProps, LObjs, In, Out, Frees):: conditionLiberation(In, Out):
nonTellContraintes(quad, Frees)!
agentQuad(LProps, LObjs, In, Out, Frees)
Tab. 8.9 { Structure generale de l'agent quadratique sous contr^ole.
Les cordes communes et/ou mediatrices de la gure peuvent ^etre recherchees et ajoutees une a une suivant un schema de contr^ole semblable a celui de l'agent quadra-tique ou une seule fois suivant un schema de contr^ole semblable a l'agent lineaire. An de privilegier la rapidite de construction, nous avons choisi de les ajouter une a une. En eet, la complexite de l'algorithme de l'agent completion d'objets est en O(n2) ou
n est le nombre d'atomes de propriete de la gure. Ainsi, en les ajoutant une a une, on espere limiter ce co^ut.
Enn, le schema de contr^ole de l'agent intervalle est semblable a celui de l'agent lineaire a la dierence qu'il ne libere aucun agent apres lui.
8.2 Modele de cooperation de GDRev 155
Il s'ensuit qu'une formulation du programme dans son ensemblesatisfaisant les pre-ferences etablies en matiere de construction peut ^etre celle decrite dans le tableau 8.10.
f
... Declarations des clauses.
.
(LProps, LObjs)^
tell(LProps = [...Specications des proprietes de la gure... j ]: tell(LObjs = [...Specications des objets de la gure... j ]! (FreeLin, InLin, OutLin,
FreeQuad, InQuad, OutQuad,
FreeCptObjs, InCptObjs, OutCptObjs, FreeInt, InInt, OutInt)^
tell(Frees = [FreesLin, FreesQuad, FreesCptObjs, FreesCptProps]): tell(FreesLin = [ j ])!
(
(FreesLin = [ j ]:
agentLin(LProps, LObjs, InLin, OutLin, Frees) ),
(FreesQuad = [ j ]:
agentQuad(LProps, LObjs, InQuad, OutQuad, Frees) ),
(FreesCptObjs = [ j ]:
agentCptObjs(LProps, LObjs, InCptObjs, OutCptObjs, Frees) ),
(FreesInt = [ j ]:
agentInt(LProps, LObjs, InInt, OutInt, Frees) )
) g
Tab. 8.10 { Architecture generale du programme de resolution de contraintes geometriques sous contr^ole.
On note que dans cette formulation seule l'execution de l'agent lineaire (la clause
agentLin) est \gardee" par une contrainte qui peut ^etre impliquee par le store. Il s'en deduit que cet agent est le seul agent qui puisse ^etre execute. Une fois son execution terminee, celui-ci libere l'agent quadratique au travers de la variable FreesQuad, qui lui delivre l'agent completion d'objets en speciant que la variable FreesCptObjs est une liste contenant au moins un element. Enn, ce dernier libere l'agent intervalle au travers de la variable FreesInt.
156 Modele de cooperation
De la sorte, on aboutit a une formulation respectant les preferences etablies, dans laquelle la rapidite de construction est privilegiee vis a vis de la complexitede la gure en terme du nombre de racines carrees calculees.
Avant de modeliser les dierents agents et leurs interactions, nous introduisons le predicat tres utile indexObjet. Il permet de retrouver l'index d'un objet dans la liste des objets a partir de son identicateur. Sa specication est telle que indexObjet(Id, LObjs, Index) est verie si et seulement si Index est l'index de l'objet identie parId
dans la liste des objets LObjs.