• Aucun résultat trouvé

HTDL : un langage de haut niveau pour la modélisation de domaines

3.2 SHPE : un moteur de planification HTN

3.2.3 HTDL : un langage de haut niveau pour la modélisation de domaines

HTDL signifie Hierarchical Task Description Language, soit « langage de description de tâches hiérarchiques » en français. Il s’agit d’un langage permettant de modéliser des domaines de planification HTN simplifiée. Sa sémantique correspond donc à celle de ce type particulier de problème de planification HTN, tel qu’il est décrit dans la sous- section 2.2.3.

Algorithm 8 trouver_premier_plan(état, réseau)

1: pile ← []

2: meilleur_plan ← [] 3: meilleur_coût ← ∞

4: empiler ([], 0, état, réseau) sur pile

5: tant que meilleur_coût = ∞ et pile n’est pas vide faire 6: suivant(pile, meilleur_plan, meilleur_coût)

7: fin tant que

Algorithm 9 trouver_meilleur_plan(état, réseau)

1: pile ← []

2: meilleur_plan ← []

3: meilleur_coût ← ∞

4: empiler ([], 0, état, réseau) sur pile 5: tant que pile n’est pas vide faire

6: suivant(pile, meilleur_plan, meilleur_coût) 7: fin tant que

synthétique et lisible. Pour cela, HTDL s’inspire largement de la syntaxe du langage Python, par exemple en forçant l’usage de l’indentation pour identifier les blocs constituant les descriptions des éléments de planification. Cette syntaxe est illustrée dans les paragraphes qui suivent à l’aide d’exemples, et une description plus formelle, utilisant la forme de Backus-Naur étendue, est disponible en annexe A.

Symboles

HTDL distingue différents types de symboles pour sa syntaxe. Il dispose tout d’abord d’un ensemble de mots réservés pour représenter les connecteurs logiques (not, and, or, imply, iff, exists, forall), des structures du langage (task, if, precond, etc.) ou des opérateurs (+, *, ==, <, etc.). Ensuite, les symboles représentant les variables sont constitués de caractères alpha-numériques et du symbole « _ », doivent commencer par une lettre minuscule, et peuvent se terminer par un ou plusieurs signes prime (exemple : x, x’, soldier, teamAlpha, team_bravo, squad2, etc.). Les symboles utilisés pour nommer les fonctions, les prédicats et les tâches sont seulement constitués de caractères alpha- numériques, et doivent commencer par une lettre majuscule (exemple : Leader, AtArea, Move, etc.). Enfin des nombres entiers et décimaux peuvent être utilisés pour représenter des constantes numériques (exemple : 0, -7, 152, 3.14, etc.).

Termes

Suivant les règles définissant la logique du premier ordre, les termes sont constitués des variables, des constantes numériques et des fonctions. Les fonctions sont constituées d’un symbole de fonction (décrit au paragraphe précédent) et d’une liste de termes, placés entre parenthèses et séparés par des virgules (exemple : Distance(area1, Area(soldier1))). Les fonctions d’arité nulle (appelées aussi constantes) peuvent être représentées avec des parenthèses vides, ou sans parenthèse (exemple : MaxDistance() ou MaxDistance).

Un certain nombre de constantes et de fonctions sont prédéfinies dans le langage. C’est par exemple le cas de la constante Undefined et des fonctions Min et Max d’arité 2, et qui sont interprétées en faisant appel à des procédures. D’autres fonctions de ce type sont intégrées au langage, mais sont appelées via les opérateurs numériques +, -,

Figure 3.4 – Précompilation de domaine

Précompilation d’un domaine de haut-niveau depuis le langage HTDL en langage C++, suivie de la compilation vers le planificateur final.

*, / et **. Ces fonctions sont aussi d’arité 2 mais s’utilisent sans parenthèse (exemple : Speed(vehicle) * Distance(route)).

Formules logiques

Les formules logiques sont constituées des formules atomiques, des conjonctions, disjonctions, des négations, implications, équivalences, et des formules quantifiées universellement et existentiellement. De plus une formule logique placée entre parenthèses est aussi une formule logique.

Les formules atomiques sont constituées de la même façon que les fonctions, c’est-à- dire par un symbole de prédicat suivi par une liste de termes entre parenthèse, séparée par des virgules. Les formules atomiques d’arité 0 (les propositions) peuvent être représentées avec ou sans parenthèse, et les opérateur logiques ==, != (différent), <, <=, > et >= sont prédéfinis et à utiliser sans parenthèse. Exemple :

InFireteam(soldier1, TeamAlpha)

Ammunition(weapon1) == 12

Distance(area1, area2) <= MaxDistance

MissionAccomplished

Les conjonctions sont formées par deux formules logiques séparées par le mot clé « and » ou par un saut de ligne. L’opérateur « and » étant associatif, il est possible d’enchainer les conjonctions. Exemple :

Soldier(soldier1) and Weapon(weapon1)

Holding(soldier1, weapon1) and Loaded(weapon1) and Antitank(weapon1)

Les disjonctions sont formées par deux formules logiques séparées par le mot clé « or ». À nouveau, cet opérateur étant associatif, on pourra enchainer les disjonctions. Exemple : NoEnemyAt(area) or AllEnemyNeutralizedAt(area)

Les négations sont formées en faisant précéder une formule logique par le mot clé « not ». Exemples :

not (Neutralized(soldier) or Wounded(soldier))

not Neutralized(soldier) and not Wounded(sodlier)

Les implications et les équivalences sont formées par deux formules logiques séparées respectivement par les mots clés « imply » et « iff ». Exemples :

NoEnemyAt(area) or AllEnemyNeutralizedAt(area) implies Safe(area)

AtArea(soldier, area) iff InArea(Position(soldier), area)

Les formules universellement quantifiées sont formées à partir du mot clé « forall », suivi d’une liste de variables, du mot clé « if », d’une première formule logique permettant de contraindre ces variables et enfin du symbole « : » suivi de la formule logique quantifiée, ou d’un nouveau bloc contenant cette formule. Exemples :

forall soldier if Soldier(soldier): Available(soldier)

forall soldier, weapon if Holding(soldier, weapon): Loaded(weapon)

Available(soldier)

Enfin, les formules avec quantificateurs existentiels sont formées à partir du mot clé « exists » suivi d’une liste de variables, du mot clé « : » et d’une formule logique, ou d’un nouveau bloc contenant cette formule. Exemples :

exists soldier, weapon: Holding(soldier, weapon) and Loaded(weapon)

exists soldier, area, route:

Area(area1) and Area(area2) and Route(route)

From(route) == AtArea(soldier) and To(route) == area Distance(route) < 10

Effets

Les effets sont regroupés dans trois types de blocs : « add » et « delete » pour les prédicats et « update » pour les fonctions. Les effets simples sont exprimés par des formules atomiques pour les prédicats ou par des affectations pour les fonctions. Les affectations sont des expressions formées d’un terme fonctionnel suivi de l’opérateur « = » et d’un second terme. Un effet conditionnel est formé d’un effet simple suivi du mot clé « if » suivi d’une formule logique. Enfin, un effet quantifié est formé d’un effet simple suivi du mot clé « forall », suivi d’une liste de variables séparées par des virgules et suivie du mot clé « if » et d’une formule logique contenant les variables quantifiées. Exemples :

add:

FireteamAt(fireteam, area_to)

At(soldier, area_to) forall soldier if InFireteam(soldier, fireteam) delete:

FireteamAt(fireteam, area_from)

At(soldier, area_from) forall soldier if InFireteam(soldier, fireteam) update:

Méthodes

Les méthodes sont des blocs formés par le mot clé « method », d’une liste optionnelle de variables séparées par des virgules, du mot clé « : » et de trois sous-blocs exprimant les préconditions, les sous-tâches et les contraintes d’ordre (chaque bloc étant optionnel). Exemple :

method soldier1, soldier2, soldier3: precond:

InFireteam(soldier1, fireteam) InFireteam(soldier2, fireteam) InFireteam(soldier3, fireteam)

soldier1 != soldier2 and soldier2 != soldier3 and soldier3 != soldier1 subtasks: n1 : Cover(soldier1, route) n2 : Move(soldier2, route) n3 : Move(sodlier3, route) order: n1 < n2, n1 < n3 Tâches

Toutes les tâches sont formées par le mot clé « task » suivi d’un symbole de tâche, d’une liste de variables placées entre parenthèses et séparées par des virgules (les parenthèses sont optionnelles si cette liste est vide), du mot clé « : » suivi par plusieurs blocs. De la nature de ces blocs dépend le type de la tâche (primitive ou composée).

Les tâches primitives peuvent contenir un bloc de préconditions, des blocs d’effets de différents types (ajout, retrait et mise à jour) ainsi qu’un bloc de coût. Ce bloc de coût contient un terme devant être de type numérique. Exemple :

task SoldierMove(soldier, route): precond:

Soldier(soldier) and Route(route) At(soldier, From(route)) add: At(soldier, To(route)) delete: At(soldier, From(route)) cost: Distance(route)

Les tâches composées ne peuvent contenir que des blocs correspondant aux méthodes de décompositions. Exemple :

task SoldierAchieveAt(soldier, area): method:

precond:

At(soldier, area) method route:

precond:

Route(route) and From(route) != area At(soldier, From(route))

subtasks:

n2 : SoldierAchieveAt(soldier, area) order:

n1 < n2

Axiomes

Certains planificateurs, tels SHOP ou UCPOP supportent la modélisation de « prédicats dérivés ». Par l’intermédiaire d’axiomes, les valeurs de ces prédicats dérivés sont liées à celles d’autres prédicats de base ou dérivés eux-mêmes. Ces prédicats dérivés apportent davantage d’expressivité à un langage de planification [106]. En effet, ils permettent par exemple d’exprimer des conditions complexes plus simplement en les modélisant hiérarchiquement, ou de déduire logiquement les conséquences de certaines actions, sans avoir à recourir à des effets complexes ou à l’introduction d’actions supplémentaires. Dans la modélisation d’un domaine traitant d’unités militaires hiérarchisées, ces axiomes permettent ainsi d’exprimer des conditions aux niveaux hiérarchiques supérieurs en fonction des conditions aux niveaux subordonnés.

HTDL intègre donc ces axiomes afin d’exprimer des prédicats ainsi que des fonctions dérivées. La syntaxe de ces axiomes est identique à celle des effets. Exemples :

FireteamAt(fireteam, area) forall fireteam, area if \ Fireteam(fireteam) and Area(area)

forall soldier if InFireteam(soldier, fireteam): SoldierAt(soldier, area)

FireteamAmmo(fireteam) = \

SoldierAmmo(soldier1) + SoldierAmmo(soldier2) + SoldierAmmo(soldier3) \ forall fireteam, soldier1, soldier2, soldier3 if \

InFireteam(soldier1, fireteam) InFireteam(soldier2, fireteam) InFireteam(soldier3, fireteam) soldier1 != soldier2 soldier2 != soldier3 soldier3 != soldier1 Domaine

Un domaine HTDL est simplement une liste d’axiomes et de tâches. HTDL ne permet pas de décrire des problèmes de planification. En effet, le but de HTDL est seulement de permettre la précompilation du domaine HTN. Les problèmes HTN doivent donc être encodés directement en C++. Des exemples de domaines HTN encodés en HTDL sont disponibles en annexe C (ces exemples intègrent toutefois des extensions qui seront introduites dans les chapitres suivants).

Documents relatifs