====== Le langage nomo ====== Le formalisme nomo repose sur la définition de [[doc:base_de_connaissances|la base de connaissances]] et de son [[doc:moteur_inference|moteur d'inférences]] complété par [[doc:creation_de_regles|le moteur de création de règles]]. Le langage nomo correspond au langage d’expression des règles et des paramètres concernant le moteur d’inférence ainsi que la base de connaissances. Le langage nomo suit la syntaxe //eXtensible Markup Language// (XML). Toutefois, l’environnement de développement nomoSDK propose un langage graphique pour définir les règles et leurs relations. Dans tous les cas, un projet nomo correspond à un document XML appelé unité. Une unité contient trois parties : une partie dédiée au dimensionnement de la base de connaissances, une partie dédiée aux paramètres du moteur d'inférence et une partie dédiée au programme. Afin de faciliter leur réutilisation, ces différentes parties correspondent à des fichiers XML importés selon la convention //XML Inclusions// (XInclude). Après un prétraitement, la validité de la syntaxe et de la cohérence d'une unité est assurée par une grammaire exprimée en //XML Schema Definition// (XSD), l'ensemble des contraintes évoquées dans la base de connaissances est pris en compte. La pseudo-compilation d'une unité donne un fichier binaire avec l'extension ”.seed” servant à l'initialisation du moteur d'inférence [[:nomoInterpreter]]. Dans le langage nomo, les unités et les documents XML inclus possèdent un entête contenant diverses informations pouvant être utilisées pour la génération de la documentation dans l'environnement [[:nomoSDK]]. Les noms des différents projets, des types ou des items doivent respecter l'expression régulière suivante : ''[a-zA-Z]+[a-zA-Z0-9_]*'' ===== Les entêtes ===== Les entêtes des documents XML appartenant au langage nomo possèdent un schéma identique. L'entête donne des informations sur le contexte du projet et sur son contenu. L’internationalisation est permise pour la description des mentions légales et pour le commentaire sur le projet. L'entête est facultatif. Il est représenté par l'élément //**header**// qui correspond, s’il existe, au premier fils de la racine du document XML. Ci-dessous un exemple d'un entête :
Le nom du programmeur La mention légale et le nom du propriétaire Le contenu ou le résumé de la licence La date du dernier enregistrement Le numéro de version La description du projet
Les éléments //**used_by**// indiquent par quel autre projet celui-ci est utilisé, cette information sert pour la propagation du renommage ou de la suppression dans le cadre de l'environnement nomoSDK et n'a pas d'incidence sur la compilation ou la validation. ===== Les unités ===== Une unité est représentée par l'élément nommé //**unit**// correspondant à la racine d'un document XML nomo. L'élément //unit// possède trois attributs : * l'attribut //**name**// indique le nom de l'unité qui sera également le nom, sans l'extension, du fichier binaire résultant de la pseudo-compilation, * l'attribut //**binaryLocation**// indique le chemin du répertoire où sera placé le fichier binaire résultant de la pseudo-compilation, * l'attribut //**multiplexer**// prend les valeurs //"yes"// ou //"no"// et indique si l'interfaçage des commandes est multiplexé. Les conséquences sur ce choix sont détaillées dans la présentation du moteur d'inférence [[:nomoInterpreter]]. L'élément //**unit**// peut contenir un élément //**header**// et doit obligatoirement dans l'ordre contenir : * un élément //**inference_engine**// précisant les paramètres du moteur d'inférence ; * un élément //**knowledge_base**// précisant les dimensions de la base de connaissances ; * un élément //**program**// contenant le programme, c'est-à-dire la base de règles initiales. Ces trois éléments peuvent être inclus via XInclude, comme le montre l'exemple ci-dessous :
...
L'extension du fichier d'une unité est ".uni". Le nom du fichier doit correspondre avec le nom de l'attribut //**name**// de la racine. ===== Le moteur d'inférence ===== Les paramètres du [[doc:moteur_inference|moteur d'inférence]] correspondent à ceux contenus dans l'élément //**inference_engine**//. L'attribut //**name**// de l'élément correspond au nom de la configuration qui doit être le nom du fichier sans l'extension. L'élément //**inference_engine**// peut contenir un entête et doit obligatoirement contenir : * l'élément //**frequency**// indiquant, avec un nombre entier strictement positif, la fréquence (en Hz) des interprétations auquel sera soumis le [[doc:moteur_inference|moteur d'inférence]], * l'élément //**forget**// correspondant au [[doc:moteur_inference#la_pertinence_des_regles|seuil de l'oubli]] d'une règle ; ce seuil est compris entre 0 et 1, * l'élément //**check_cover**// indiquant le coefficient de couverture //c// qui sera utilisé pour déterminer la durée de l'évaluation d'une [[doc:base_de_connaissances#les_regles_de_controle|prédiction]], * l'élément //**bid_rate**// correspondant au [[doc:moteur_inference#l_enchere|taux de l'enchère]], le taux est un nombre décimal positif, * l'élément //**reimbursement_rate**// correspondant au [[doc:moteur_inference#le remboursement|taux du remboursement]], le taux est un nombre décimal positif, * l'élément //**tax_rate**// correspondant au [[doc:moteur_inference#la_taxe|taux de la taxe]], le taux est un nombre décimal positif, * l'élément //**reward_rate**// correspondant au [[doc:moteur_inference#la_recompense|taux de la récompense]], le taux est un nombre décimal positif. L'exemple ci-dessous représente la configuration par défaut avec aucune dynamique :
...
L'extension du fichier des paramètres du moteur d'inférence est ".eng". ===== La base de connaissances ===== Les dimensions de la [[doc:base_de_connaissances|base de connaissances]] sont décrites dans l'élément //**knowledge_base**//. L'attribut **//name//** de l'élément correspond au nom de la configuration qui doit être le nom du fichier sans l'extension. L'élément //**knowledge_base**// contient obligatoirement : * un élément //**time_span_limit**// correspondant à la valeur positive maximale de l'indice temporel d'un évènement dans la [[doc:base_de_connaissances#la_base_de_faits|mémoire évènementielle]], elle s'exprime implicitement en nombre de pas ou en milliseconde en ajoutant 'ms', * un élément //**maximum_of_maximizations**// indiquant le nombre maximal d'ajustements d'une règle, soit un entier positif, * un élément //**maximum_of_internal_events**// correspondant au nombre maximum d'évènements par type contenu dans la mémoire évènementielle. Les types appartiennent à toutes les catégories sauf celles relatives aux entrées. Ce nombre doit être supérieur ou égal à un, * un élément //**maximum_of_external_events**// correspondant au nombre maximum d'évènements par type d'entrée contenu dans la mémoire évènementielle. Ce nombre doit être supérieur ou égal à un, * un élément //**maximum_of_rules_by_type**// correspondant au nombre maximum de règles par type contenu dans la mémoire évènementielle. Ce nombre doit être supérieur ou égal à un, * un élément //**maximum_of_premises**// indiquant le nombre maximal de prémisses d'une règle, soit un entier strictement positif. Les éléments //**maximum_of_maximizations**//, //**maximum_of_internal_events**//, //**maximum_of_rules_by_type**//, //**maximum_of_premises**// contraignent directement le contenu du programme. Toutefois, s’il est souhaité que ce soit le programme qui contraigne ces valeurs, alors la valeur //"auto"// peut être utilisée pour signifier que la valeur sera déduite automatiquement d'après le contenu du programme. L'exemple ci-dessous représente la configuration par défaut avec l'utilisation de valeurs automatiques :
...
L'extension du fichier contenant les dimensions de la base de connaissances est ”.bas”. ===== Les modèles ===== Avant d'aborder les programmes, il est nécessaire de présenter les modèles qui seront utilisés dans les programmes. Un modèle correspond à la définition d'un ensemble de [[doc:base_de_connaissances|types de connaissance]] avec leur espace de définition (énumération des items disponibles). Chaque type du modèle appartient à l’une des douze catégories prédéfinies : entrée (//**input**//), commande (//**command**//), perception (//**perception**//), conception (//**conception**//), prédiction (//**prediction**//), marque (//**landmark**//), opération (//**operator**//), désignation (**scope**), transition (//**transition**//), anomalie (//**anomaly**//), contrôle (//**check**//) et récompense (//**reward**//). [[doc:base_de_connaissances#Les_regles_selon_leur_categorie|Certains types]], de par leur catégorie, impliquent nécessairement la présence d’autres types et peuvent introduire des contraintes sur leur ensemble de définitions. Ces interdépendances forment des structures. Certains types ou structures peuvent dépendre de l’existence au préalable d’un autre type ou d’une autre structure. Un modèle est décrit dans un élément //**model**// dont l'attribut //**name**// indique son nom ainsi que le nom du fichier sans l'extension. Cet élément peut posséder un entête ainsi qu'une base mais il doit obligatoirement avoir une définition. Ci-dessous une ébauche d'un modèle :
...
... ...
L'extension d'un fichier contenant un modèle est ".mod". Dans le cadre de l'utilisation de l'environnement [[:nomoSDK]], un élément supplémentaire contenant des informations sur la représentation des types peut être rajouté à la fin du document XML de modèle mais cet élément ne fait pas partie du langage nomo en tant que tel. ==== La base ==== Un modèle peut être une extension d'un autre modèle servant de base. Dans ce cas, le modèle étendu correspond au modèle de base avec des types supplémentaires ou avec des ensembles de définitions enrichis. L'ajout de relations entre types est également permis, comme l'illustre l'[[#les_structures_perceptives|exemple de structure perceptive]]. Seul le mécanisme d'extension est autorisé, c'est à dire que la suppression de type ou une restriction des ensembles de définition sont interdites. L'utilisation du mécanisme d'extension sert à structurer les développements et à valider le respect des dépendances. Concrètement, l'élément //**base**// contient un et un seul modèle à étendre et l'élément //**definition**// les nouveaux types ou les types à étendre contenant uniquement les nouveaux items. ... ... ==== La définition de types ==== Selon leur catégories, les types sont définis individuellement ou au sein de structure. L'élément //**definition**// peut contenir des types de commande (élément //**command_type**//), des types de conception (élément //**conception_type**//), des types de marque (élément //**landmark_type**//), des types de récompense (élément //**reward_type**//), des structures perceptives (élément //**perceptive_structure**//), des structures prédictives (élément //**predictive_structure**//) et une unique structure de création de règles (élément //**plant_structure**//). Dans un même modèle, il ne peut y avoir de type ayant le même nom au sein d'une même catégorie. Avant d'aborder en détail chacun de ces éléments, voici quelques éléments qui leur sont communs. L'ensemble de définitions des types correspond à une liste d'items contenue dans un élément //**items**//. Les éléments //**item**// dont le nom correspond à la valeur de l'attribut //**name**//. Au sein d'un élément //**items**//, le nom de chaque item doit être unique. Les composantes des vecteurs d'entrée ou de sortie sont définies au sein d'un élément //**components**//. Chaque composante se traduit par un élément //**components**// dont le nom correspond à la valeur de l'attribut //**name**// ; le nom de chaque composante doit être unique. L'ordre des composantes représente leur position dans le vecteur. Lorsque l'annotation de commentaire est permise, celle-ci prend la forme d'un élément //**annotation**// possédant un ou des éléments //**documentation**// avec un attribut spécifiant la langue //**xml:lang**// et avec pour contenu le commentaire, comme ci-dessous : Un commentaire. A comment. Chaque élément //**iem**// ou //**component**// peut contenir une annotation. === Les types de conception === L'élément //**conception_type**// définit un type de [[doc:base_de_connaissances#Les_regles_de_conception |conception]], l'attribut //**name**// indique son nom. L'élément //**conception_type**// contient obligatoirement un élément //**items**//. L'élément //**conception _type**// peut contenir également : * un élément //**annotation**//, * un élément //**rewarded_by**// dont l'attribut //**name**// renvoie au nom du type de récompense défini dans le modèle, * un élément //**predicted_by**// dont l'attribut //**name**// renvoie au nom de la structure prédictive définie dans le modèle. Un type de conception peut être défini à l'intérieur d'un autre type. Dans ce cas, le type de conception ainsi défini correspond à un type jumeau, Son ensemble de définition doit être contenu dans l'ensemble de définition du type qui le définit Si l'élément //**conception_type**// est défini à la racine de l'élément //**definition**//, alors il peut contenir également un élément //**conception_type**// correspondant à son type jumeau, comme dans l'exemple suivant : Un commentaire. === Les types de commande === L'élément //**command_type**// définit un type de [[doc:base_de_connaissances#Les_regles_de_commande|commande]], l'attribut //**name**// indique son nom. L'élément //**command_type**// doit contenir obligatoirement deux éléments : * un élément //**items**//, * un élément //**components**//. L'élément //**command_type**// peut contenir trois autres éléments : * un élément //**annotation**//, * un élément //**rewarded_by**// dont l'attribut //**name**// renvoie au nom du type de récompense défini dans le modèle, * un élément //**conception_type**// dont la liste des items doit être contenue dans celle du type de commande. === Les types de récompense === L'élément //**reward_type**// définit un type de [[doc:base_de_connaissances#Les_regles_de_recompense|récompense]], l'attribut //**name**// indique son nom. L'élément //**reward_type**// doit contenir obligatoirement un élément //**items**// et éventuellement un élément //**annotation**// ou un élément //**conception_type**//. Ci-dessous, le type de récompense associé à l'exemple du type de conception ci-dessus : === Les types de marque === L'élément //**landmark_type**// définit un type de [[doc:base_de_connaissances#Les_regles_de_marquage|marque]], l'attribut //**name**// indique son nom. Le nom du type correspond obligatoirement au nom du type de récompense auquel il est associé. Le type de marque définit ici est utilisé indépendamment de toute structure prédictive. L'élément //**landmark_type**// doit contenir obligatoirement un élément //**items**//. L'élément //**landmark_type**// peut contenir également : * un élément //**annotation**//, * un élément //**rewarded_by**// dont l'attribut //**name**// renvoie au nom du type de récompense défini dans le modèle, * un élément //**conception_type**//. Ci-dessous, un exemple de définition d'un type de marque : === Les structures prédictives === Une [[doc:base_de_connaissances#Les_regles_de_prediction|structure prédictive]] définit trois types associés: un type de prédiction, un type de marque et un type de contrôle. Ces trois types possèdent le même ensemble de définitions. L'attribut //**name**// correspond au nom de ces trois types au sein de leur catégorie. L'élément //**predictive_structure**// décrivant cette structure contient obligatoirement un élément //**items**//. L'élément //**predictive_structure**// peut contenir également : * un élément //**annotation**//, * un élément //**rewarded_by**// dont l'attribut //**name**// renvoi au nom du type de récompense défini dans le modèle, * un élément //**conception_type**//. Si l'élément //**rewarded_by**// est présent, cela signifie que ce sont les trois types de règles qui sont susceptibles d'être rétribués. Ci-dessous, un exemple de définition d'une structure prédictive minimale dans l'idée d'étendre l’ensemble de définitions lors de la création de règles au cours des interprétations : === Les structures perceptives === Une [[doc:base_de_connaissances#Les_regles_de_perception|structure perceptive]] définit deux types associés : un type d'entrée et un type de perception. L’élément //**perceptive_structure**// décrivant cette structure contient obligatoirement : * Un élément //**items**// qui correspond à l'ensemble de définitions du type de perception. Un type d'entrée ne possède pas d'ensemble de définitions. Les vecteurs d'entrée étant des valeurs continues, ce sont les prémisses des règles de perception qui caractérisent en quelque sorte l'ensemble de définitions. * Un élément //**components**// correspond aux composantes du vecteur d'entrée. L'élément //**predictive_structure**// peut contenir également : * un élément //**annotation**//, * un élément //**rewarded_by**// dont l'attribut //**name**// renvoie au nom du type de récompense défini dans le modèle, * un élément //**predicted_by**// dont l'attribut //**name**// renvoie au nom de la structure prédictive définie dans le modèle, * un élément //**conception_type**//, * un élément //**command_type**// correspondant à la définition d'un type de commande lié à cette structure perceptive. L'ensemble de définitions du type de commande doit être inclus dans celle du type de perception. L'élément //**command_type**// n'a dans ce cas pas d’élément //**components**// puisque celui-ci correspond à celui du type d'entrée. Le type de commande possède le même nom que la structure perceptive, par conséquent ; il ne possède pas d'attribut //**name**//. Ci-dessous un exemple de structure perceptive avec un type de commande lié : === La structure de création de règles === Une structure de création de règles dans un modèle correspond à l'extension d'une structure de création de règles prédéfinies qui déclare les types et leurs ensembles de définition de base imposés par le moteur de création de règles. La structure de création de règles prédéfinie déclare six types avec leur ensemble de définitions. == Le type transition == Le type transition (nommé en langage nomo //**transition**//) correspond au seul et unique type de la catégorie de connaissance relative aux [[doc:creation_de_regles#Les_etats_internes|transitions]]. Son ensemble de définitions correspond aux quatre transitions d'états du moteur de création de règles permises directement par des événements : * la transition vers l'état « Affectation » nommée //**begin_affectation**//, * la transition vers l'état « Inhibition » nommée //**begin_inhibition**//, * la transition vers l'état « Excitation » nommée //**begin_excitation**//, * la transition vers l'état « Finalisation » nommée //**begin_finalization**//. Cet ensemble de définitions ne peut être étendu dans un modèle. == Les types dédiés au registre des entrées == L'utilisation d'un registre s'appuie sur deux types, l'un appartenant à la catégorie de connaissances relatives aux opérateurs et l'autre appartenant à la catégorie de connaissances relatives aux désignations. Pour le registre dédié aux entrées, cette paire de types dans le langage nom est nommé //**register_00**//. Le type //**register_00**// de la catégorie relative aux opérateurs (//**operator**//) a pour ensemble de définitions les [[doc:creation_de_regles#La_copie_d_un_evenement|opérateurs d'affectation]], soit les opérateurs suivant : * « prendre celui-là » nommé //**get_there**//, * « prendre le début » nommé //**get_first**//, * « prendre le précédent » nommé //**get_before**//, * « prendre le dernier » nommé //**get_last**//. * « prendre le suivant » nommé //**get_after**//. Les opérateurs [[creation_de_regles#la_construction_des_premisses|« créer une prémisse »]] spécifiant la tolérance que les informations de la prémisse d'entrée à créée, sont aussi à rajouter dans le cadre d'une extension. L'élément //**item**// définissant un de ces opérateurs « créer une prémisse» contient un élément //**premisse**// contenant à son tour l'élément //**information**// dont l'attribut //**tolerance**// correspond à la tolérance initiale des informations. ... Le type //**register_00**// de la catégorie relative aux [[doc:creation_de_regles#les_references|désignations]] (//**scope**//) a pour ensemble de définitions les items correspondant aux types autorisés à être référencés. Ces items contiennent un élément //**target**// possédant un triplet d'attribut spécifiant la catégorie (//**category**//), le modèle (//**model**//), et le nom du type (//**type**//). Dans le cas du //**register_00**//, la valeur de l'attribut de la catégorie se trouve fixée à //**input**//, la valeur du modèle peut prendre soit la valeur //**this**// désignant le modèle dans lequel il est définit, soit la valeur //*****// désignant l'ensemble des modèles du programmes mais pas ceux des sous-programmes sauf s'ils sont importés. A l'édition des liens du programme, toute une désignation doit porter sur au moins un type. == Les types dédiés aux autres registres == Le nombre des autres registres définis dans l'extension détermine le nombre de paires de types dédiés aux autres registres, chaque paire de types a le même nom //**register_**//, suivi du numéro du registre précédé d'un zéro si inférieur à dix. Le nombre des autres registres égal ou supérieur à un, par conséquent la paire de types //**register_01**// est toujours défini. Tous les types de même catégorie dédiée aux autres registres que le registre d'entrée ont le même ensemble définitions. Les types de la catégorie relative aux opérateurs (//**operator**//) ont pour ensemble de définitions les [[doc:creation_de_regles#l_affectation_des_items|opérateurs d'affectation]], soit les opérateurs suivant : * « prendre celui-là » nommé //**get_there**//, * « prendre le début » nommé //**get_first**//, * « prendre le précédent » nommé //**get_before**//, * « prendre le dernier » nommé //**get_last**//, * « prendre le suivant » nommé //**get_after**//, * « prendre le même » nommé //**get_same**//, * « cibler celui-là » nommé //**target**//, * « copier » nommé //**copy**//, * « créer un concept » nommé //**create_conception**//, * « créer une récompense » nommé //**create_reward**//, * « créer une marque» nommé //**create_landmark**//, * « créer une commande » nommé //**create_command**//, * « créer un concept jumeau » nommé //**create_twin**//, * « créer une perception décalée» nommé //**create_perception_forward**//, * « créer une prédiction » nommé //**create_prediction**//, * « créer un contrôle décalé » nommé //**create_check_forward**//. Les opérateurs liés au repère temporel : * « transformer en repère temporel » nommé //**transform_in_temporal_reference**//, * « transformer en repère et origine temporel » nommé //**transform_in_temporal_reference_and_origin**//. Et les opérateurs liés à la manipulation des indices temporels : * « s'aligner sur » nommé //**same_time**// * « avancer » nommé //**forward**// * « reculer » nommé //**backward**// Les éléments //**item**// qui servent à définir les opérateur [[creation_de_regles#la_construction_des_premisses|« créer une prémisse »]] contiennent un élément //**premise**// pouvant avoir comme triplet d'attributs //**type**//, //**model**// et //**category**//. Ce triplet d'attribut s'impose lorsque l'information est précisée ou lorsque l'indice temporel spécifié est négatif. En dehors, de ces cas il n'est pas nécessaire de spécifié le type car si l'information n'est pas spécifié ce sera l'information de l'item qui sera utilisée et dans ce cas une vérification du type sera effectué entrainant une anomalie si incohérence. L'élément //**premise**// doit contenir obligatoirement les trois éléments suivant //**information**//, //**credibility**// et //**timespan**// avec pour attribut //**tolerance**// et éventuellement l'attribut //**value**// sous réserve de sa cohérence avec le type lors de l'édition des liens du programme. Naturellement, la tolérance pour l'information ne peut être que infinie ou nulle. Par exemple : ... Les éléments //**item**//, qui servent à définir les opérateur [[creation_de_regles#la_construction_des_conclusions|« créer une conclusion»]], contiennent un élément //**conclusion**// avec obligatoirement deux attributs qui renvoient aux valeurs initiales d'une règle : l'espérance (nommée //**relevance**//) et le nombre d'ajustements (nommé //**fitting_nbr**//). Le nombre d'ajustements sert à donner, si c'est souhaité, une certaine inertie à l'adaptation de la nouvelle règle, en considérant qu'elle résulte d'une moyenne effectuée sur une valeur fois le nombre d'ajustement plus un. L'élément //**conclusion**// peut contenir l'élément //**information**// avec l'attribut //**value**//, l'élément //**delay**// avec l'attribut //**value**// ou l'élément //**target**// avec le triplet d'attributs //**type**//, //**model**// et //**category**//. L'élément //**target**// s'impose uniquement lorsque l'information est précisée ou lorsque le délai est spécifié et non nul. En dehors, de ces cas il n'est pas nécessaire de spécifié le type car si l'information n'est pas spécifié ce sera l'information de l'item qui sera utilisée et dans ce cas une vérification du type sera effectué entrainant une anomalie si incohérence. Les types de la catégorie relative aux désignations (//**scope**//) suivent également le même schéma que pour le registre d'entrée, hormis le fait que la catégorie puisse prendre une liste toutes les valeurs sauf //**input**//, soit : la perception (//**perception**//), la conception (//**conception**//), la commande (//**command**//), la prédiction (//**prediction**//), le marquage (//**landmark**//), le contrôle (//**check**//), la récompense (//**reward**//), la transition (//**transition**//), l'opération (//**operator**//, la désignation (//**scope**//), l'anomalie (//**anomaly**//), soit //*****// désignant l'ensemble des catégories possibles. L'attribut //**model**// peut prendre soit la valeur //**this**//, soit la valeur //**plant**//, soit les deux, soit //*****// désignant tous les modèles du programme hormis ceux des sous-programmes non-importés. La valeur //**plant**// désigne le modèle de la structure de création de règles prédéfinie. == Le type anomalie== Le type anomalie (nommé en langage nomo //**anomaly**//) correspond au seul et unique type de la catégorie relative aux [[doc:creation_de_regles#Les_etats_internes|anomalies]]. L'ensemble de définition, qui ne peut être étendu dans un modèle, correspond dans l'ordre à : ... La description de l'extension de la structure de création de règles se traduit alors par un élément //**plant_structure**// ayant pour attribut //**others_register**// indiquant le nombre des registres autres que le registre s'occupant des entrées. Cet élément contient obligatoirement deux autres éléments décrivant réciproquement les types dédiés au registre d'entrée //**input**// et ceux d'un registre prototypique dédié aux autres types d'évènements //**other**//. Ces deux éléments contiennent deux éléments correspondant réciproquement aux extensions des ensembles de définition des opérateurs et des désignations. L'extension de la structure de création de règles peut contenir un élément //**reward_by**// qui indique le type de récompense associé pour tous les types définis. Ci-dessous un exemple d'une extension de la structure de création de règle : La validité de l'ensemble des attributs est effectuée totalement uniquement à l'édition des liens de l'unité utilisant une instance du modèle contenant un élément //**plant_structure**//. La liste des anomalies que peut généré le moteur de création de règles en cas de mauvais utilisation : |AFFECTATION_EXPIRED_FOR_REFERENCE_TIME |ILLEGAL_OPERATOR_IN_CONDITION | |AFFECTATION_EXPIRED_FOR_SHIFTING_TIME |ILLEGAL_REFERENCE_FOR_CREATION | |AFFECTATION_EXPIRED_OPERATOR_FOR_TARGET |ILLEGAL_REFERENCE_FOR_INPUT_CONDITION | |ALREADY_AFFECTED_CHUNK |ILLEGAL_REFERENCE_FOR_INTERNAL_CONCLUSION | |ALREADY_CREATED_PERCEPTION |ILLEGAL_REFERENCE_FOR_INTERNAL_CONDITION | |ALREADY_DESIGNED_REFERENCE_TIME |ILLEGAL_REFERENCE_FOR_PERCEPTION_CONCLUSION | |ALREADY_DESIGNED_TARGET |ILLEGAL_START_IN_AFFECTATION | |BAD_REFERENCE_TIME |ILLEGAL_START_IN_CONCLUSION | |EXPIRED_EXTERNAL_CHUNCK |ILLEGAL_START_IN_EXCITATORY_PREMISE | |EXPIRED_INTERNAL_CHUNCK |ILLEGAL_START_IN_INHIBITORY_PREMISE | |EXPIRED_INTERNAL_TARGET |ILLEGAL_START_IN_STANDBY | |FAIL_CHUNCK_INACTIVE |ILLEGAL_TARGET_IN_EXTERNAL_CHUNK | |FAIL_LANDMARK_ID |INPUT_PREMISE_IN_INHIBITORY_PREMISE | |FAIL_LANDMARK_TYPE |INPUT_PREMISE_MISSING | |FAIL_LINKED_PERCEPTION |MISSING_LANDMARK_RULE | |FAIL_PERCEPTION_OF_COMMAND_CONCLUSION |MISSING_PREDICTIVE_RULE | |FAIL_PREDICTION_ID_IN_CHECKING_RULE |MISSING_TARGET_FOR_AFFECTATION_OPERATOR | |FAIL_PREDICTIVE_TYPE_IN_CHECKING_RULE |NO_UNIQUE_COMMAND_CONCLUSION | |FAIL_SEARCH_EVENT |NO_UNIQUE_PERCEPTION_CONCLUSION | |FAIL_TARGETED_AFFECTATION |NO_UNIQUE_PREDICTION_CONCLUSION | |FORBIDDEN_REFLECTION_RETURN_IN_CONCLUSION |OVER_AFFECTATION_OPERATORS_FOR_TARGET | |ILLEGAL_CREATION_OPERATOR_IN_EXTERNAL_CHUNK |OVER_INPUT_PREMISE | |ILLEGAL_CREATION_OPERATOR_IN_INTERNAL_CHUNK |OVER_INTERNAL_PREMISES_NUMBER | |ILLEGAL_LANDMARK_TYPE |OVER_RULES | |ILLEGAL_OPERATOR_IN_AFFECTATION |OVER_TIME_SPAN_FOR_INTERNAL_CONDITION | |ILLEGAL_OPERATOR_IN_CONCLUSION |SAME_TIME_CONDITION_CONCLUSION | ===== Les programmes ===== Un programme est décrit par l'élément //**program**//. L'attribut name de l'élément correspond au nom de la configuration qui doit étre le nom du fichier sans l'extension. L'élément //**program**// contient directement deux éléments : * l'élément //**subprograms**// listant les programmes inclus dans le programme principal, * l'élément //**body**// correspondant au corps du programme qui contient à la fois les règles et leurs modèles. Un programme doit contenir au minimum soit un élément //**subprograms**//, soit un élément //**body**//. Ci-dessous l'exemple d'une ébauche de programme :
...
... ...
L'extension du fichier d'un programme est ”.prg”. Dans le cadre de l'utilisation de l'environnement [[:nomoSDK]], un élément supplémentaire contenant des informations sur la représentation et sur la validation des règles peut être rajouté à la fin du document XML de programme mais cet élément ne fait pas partie du langage nomo en tant que tel. ==== Les sous-programmes ==== En dehors du programme principal, les autres programmes sont considérés comme des prototypes de programme qu'il est possible d'instancier comme sous-programme. L'instanciation correspond à l'insertion d'une copie d'un programme dont les noms des règles et des types seront renommés en fonction du nom de l'instance. Plusieurs sous-programmes peuvent être l'instance d'un même programme et peuvent être interprétés indépendamment les uns des autres. Le programme instancié est contenu dans l'élément //**new**// dont l'attribut //**instance**// correspond au nom de l'instance. Deux instances du même programme ne peuvent avoir le même nom lors de la pseudo-compilation. Afin de contrôler la création des instances, il est possible de créer une nouvelle instance uniquement si aucune autre instance n’existe dans un programme parent. Dans ce cas, le programme susceptible d'être instancié est contenu dans l'élément //**inherite**// dont l'attribut //**instance**// correspond au nom de l'instance. Dans l'exemple ci-dessous, deux sous-programmes représentent deux agents différents définis par le programme prototype "agent". Le sous-programme "mon_alarme" correspond à l'instance du programme "alarme" dans le cas où "mon_programme" est le programme principal. ... Si le programme "agent" déclare un nouveau sous-programme (élément //**new**//) nommé "mon_alarme" alors, il sera considéré comme étant un sous-programme distinct du sous-programme "mon_alarme" du programme parent. Si le programme "agent" déclare un sous-programme hérité (élément //**inherite**//) nommé "autre_alarme" alors, il sera considéré comme étant un sous-programme distinct du sous-programme "mon_alarme" du programme parent. Si le programme "agent" déclare un sous-programme hérité (élément //**inherite**//) nommé "mon_alarme" alors, il sera considéré comme étant le sous-programme "mon_alarme" du programme parent. Au sein d'un élément //**subprograms**//, toutes les instances doivent posséder un nom unique. Un exemple d'utilisation de ces différentes manières d'instancier se trouve dans la [[tutoriel:genie_logiciel#tutorielles_principes_de_genie_logiciel|troisième partie du tutoriel]]. ==== Le corps du programme ==== Le corps d'un programme est composé de deux éléments. Le premier élément, nommé //**models**//, contient tous les modèles utilisés par le programme et le second , nommé //**scheme**//, contient le schème global. Un schème représente un ensemble de règles et de schèmes. ... ... ... Pour tous les éléments du corps une annotation est permise. === Les modèles === De la même manière que pour les sous-programmes, il faut instancier les modèles. L'instanciation a pour effet de recopier le modèle et de modifier le nom des types en fonction de l'instance. Il est donc possible d'avoir deux instances du même modèle sans confusion aucune entre les types. Il existe trois manières différentes d'instancier un modèle : soit en déclarant obligatoirement une nouvelle instance, soit par héritage, soit par importation. Ces trois manières d'instancier se traduisent par un élément particulier avec pour attribut //**instance**// le nom de l'instance contenant le modèle à instancier. Par ailleurs, chacun de ces éléments doit contenir le prototype de modèle à instancier : * La première manière d'instancier s'effectue directement par l’intermédiaire d'un élément //**new**//. * L’instanciation par héritage est indiquée par l'élément //**inherite**//. Dans ce cas, si aucune autre instance dans un programme parent de même nom existe et qu'il contient le modèle désigné, alors une nouvelle instance est créée, sinon l'instance considérée sera l'instance préexistante du programme parent. Soit le modèle //M1// et le modèle //M2// ayant pour base //M1//, si leur nom d'instance concorde, //M1// peut hériter de //M2// mais //M2// ne peut être hérité à partir de //M1//. Par ailleurs, un modèle ne peut pas hériter d'une nouvelle instance frère ni d'un modèle importé. * La dernière manière d'instancier un modèle correspond à importer une instance d'un modèle appartenant à un sous-programme via l'élément //**import**//. L'attribut //**subprogram**// permet de d'indiquer le sous-programme visé et l'attribut //**instance**// indique le nom de l'instance du modèle dans le sous-programme et qui doit être repris dans le programme parent. Un élément //**models**// contient obligatoirement au moins une instance. Au sein d'un élément //**models**// tous les noms des instances de modèles doivent être différents. L'exemple suivant illustre les trois instanciations possibles : Dans le cas où le modèle a été définit au sein du programme, le chemin du modèle est indiqué à l'aide de la norme XPointer comme suit : Un exemple d'utilisation de ces différentes manières d'instancier se trouve dans la [[tutoriel:genie_logiciel#tutorielles_principes_de_genie_logiciel|troisième partie du tutoriel]]. === Les schèmes et les règles === Un schème représente un ensemble de règles et de schèmes. Un schème est représenté par un élément //**scheme**// dont le nom est indiqué par l'attribut //**name**//. Le schème global contient tous les schèmes et non celui correspondant au nom du programme, de sorte qu'il ne possède pas l'attribut //**name**//. Les règles contenues dans les schèmes sont décrites par l'élément //**rule**// qui possède trois attributs : * le nom de la régle (//**name**//), * la pertinence (//**relevance**//), * le nombre d'ajustements (//**fitting_nbr**//), lorsqu'il n'est pas souhaité d'effectuer de nouveaux ajustements, il est considéré infini et prend la valeur "INF". Si l’attribut //**relevance**// est omis alors il sera considéré à 1. Si l’attribut //**fitting_nbr**// est omis alors il sera considéré valant "INF". Une règle contient éventuellement des prémisses mais contient obligatoirement une conclusion. Une prémisse est représentée par l'élément //**premise**// possédant trois attributs : * le type visé par la prémisse (//**type**//), * l'instance du modèle définissant le type (//**model**//), * la catégorie du type (//**category**//). Si la prémisse vise un évènement relatif à une entrée, alors la prémisse contient autant d'éléments //**information**// que de composantes définies par le type associé. L'ordre de ces éléments doit correspondre à l'ordre défini par le type associé. Chaque élément //**information**// possède dans ce cas deux attributs : * la valeur de la composante (//**value**//), * la tolérance associée à cette valeur (//**tolerance**//). Si la prémisse vise un type d'événement autre qu'un événement relatif à une entrée, alors la prémisse contient trois éléments représentant l'information (//**information**//), la crédibilité (//**credibility**//) et l'indice temporel (//**timespan**//). Chacun de ces éléments possède deux attributs relatifs à leur valeur (//**value**//) et à leur tolérance (//**tolerance**//). Si la prémisse est inhibitrice, l'attribut //**inhibitor**// à la valeur "true" doit être ajouté à l'élément //**premise**//. Par ailleurs, si la crédibilité et l'indice temporel sont omis alors ils auront respectivement pour les couples (valeur,tolérance) suivant (1,INF) et (0,INF). Pour l'indice temporel (//**timespan**//) s'exprime soit en milliseconde auquel cas il faut rajouter 'ms' après la valeur, soit en nombre de pas. Deux constantes peuvent être également utilisé 'MIN' et 'MAX' représentant réciproquement les bornes inférieur et supérieur de la mémoire. 'MIN' représente le nombre maximum de pas de retard pour une intention et 'MAX' représente le nombre maximum de pas inférieur à //**time_span_limit**//. Il est possible d'ajouter des pas ou des millisecondes à 'MIN', de même il est possible de retrancher à 'MAX' des pas ou des millisecondes tant que le résultat est supérieur à zéro. Plus précisément,dans la version 2013 du moteur nomoInterpreter, le 'MIN' en terme de pas se calcule en arrondissant à l'inférieur comme suit : MIN=-231-1*frequecy1000 Par ailleurs, la tolérance associée à l'indice temporel (//**timespan**//) peut être exprimée en fonction du pas temporel en ajoutant le mot clé 'period' ou 'periods'. Dans une prémisse, si un élément possède un attribut //**tolerance**// à "INF", il n'est alors pas nécessaire d'avoir l'attribut //**value**//. Sauf pour l'indice temporel où l'attribut doit être renseigné pour indiquer le signe déterminant s’il s'agit d'une intention. Une conclusion est représentée par l'élément //**conclusion**// avec trois attributs : * le type de la conclusion (//**type**//), * l'instance du modèle définissant le type (//**model**//), * la catégorie du type (//**category**//) L'élément //**conclusion**// contient un élément //**information**// avec un attribut //**value**// donnant la valeur de la conclusion. Si la conclusion est une prédiction ou une conception avec un délai alors un attribut indiquant le délai (//**delay**//) doit être rajouté. Ce délai peut correspondre soit un simple nombre naturel représentant un nombre de pas, soit un nombre naturel suivis de 'ms' signifiant qu'il s'agit de millisecondes, soit 'MAX' représentant le nombre de pas maximales pour un délais. Il possible de retrancher à la valeur 'MAX' soit un nombre de pas soit un nombre de milliseconde, par exemple : 'MAX - 10ms'. Plus précisément,dans la version 2013 du moteur nomoInterpreter, le 'MAX' en terme de pas se calcule en arrondissant à l'inférieur comme suit : MAX=231-1*frequecy1000 À noter, la constante 'MAX' pouvant être utilisée pour l'attribut //**delay**// correspond à la constante 'MIN' de pouvant être utilisée pour la valeur de //**timespan**// avec un signe opposé. Si la conclusion est une commande, alors l'élément contient autant d'éléments //**output**// que de composantes définies par le type associé. L'ordre de ces éléments doit correspondre à l'ordre défini par le type associé. Chaque élément //**output**// possède un attribut //**value**// indiquant la valeur de la composante. Dans le cas des prémisses ou des conclusions appartenant à la catégorie des opérateurs ou des désignations, l'attribut //**value**// (de l’élément //**information**//) est remplacé par les attributs nécessaires à la description de l'item évoqué. Par exemple, pour une prémisse visant une désignation, l'information possède à la place de //**value**// : //**target_category**//, //**target_model**// et //**target_type**//. Ci-dessous un exemple d'un schème global rappelant les différentes configurations en dehors de règles liées aux catégories relatives aux opérations et aux désignations. La règle "start" se déclenche à la première interprétation puis est éliminée car elle a une espérance nulle. Son déclenchement produit une intention à durée infinie qui sera supprimée au déclenchement de la règle "end". Ce dernier sera déclenché lorsque la commande "alert" sera envoyée au déclenchement de la règle “action”. La règle "action" se déclenchera à l'arrivée d'une perception “perception_1” et s’il y a une intention "start" et s'il n'y a pas eu de commande à la dernière interprétation. La règle de détection se déclenchera lorsque un évènement approprié arrivera et si l'intention "start" est présente dans la base de faits. Dans le [[tutoriel:introduction|tutoriel]] se trouvent de nombreux exemples de programme.