====== nomoSDK : les macros ======
Les macros correspondent à des simplifications d'écriture pour décrire un ensemble de règles. Contrairement aux formalismes qui décrivent à la fois le modèle et les règles, une macro décrit uniquement des règles. De même, un formalisme est exclusif alors que les macros peuvent être multiples au sein d'un programme.
Une macro se traduit par un élément **//macro//** à la racine de l'élément //**sdk**//. L'attribut booléen //**active**// indique si la macro conduira à la génération de règles, si il est omis, il sera considéré comme à "//false//". L'attribut obligatoire //**name**// indique le nom de la macro qui sera également utilisé pour le nom du schème créé afin de regrouper les règles générées. L'attribut "scheme" indique le schème parent du schème créé, lorsque cet attribut est omis cela signifie que le schème parent correspond au schème principal.
Les macros peuvent répliquer une même structure de règles avec des valeurs différente à l'aide de variables. Ces variables renvoient aux colonnes d'un tableaux de valeurs dont chaque ligne correspond à une instance des règles décrites dans le patron.
Le tableaux de valeurs est décrit dans l'élément //**csv**// selon le format CSV (sans apostrophe simple ou double). Une variable dans une règle est indiqué par la présence d'un dièse '#' devant le nom de celle-ci. Toutes les valeurs des attributs, hormis l'inhibition, peuvent être modifié de cette façon.
Si le nom des règles ne provient pas des données CSV, alors le nom de la règle prototype sera suffixé pour chaque nouvelle règle par un souligné et le numéro de la ligne CSV traitée.
Par ailleurs, l'élément //**csv**// peut recevoir comme attribut //**select**// dont la valeur correspond au numéro de ligne initiale et de ligne finale des données devant être appliquées, soit l'expression régulière : 1-9]+[0-9]*[ ]+to[ ]+[1-9]+[0-9]*
En l'absence de l'attribut //**select**//, l'ensemble des données sera utilisé.
Le contenu du CSV peut être soit indiquer directement dans le format texte CSV et dans ce cas rajouter l'attribut //**xsi:type**="embedded"//, soit importer les données via le protocole XInclude et dans ce cas rajouter l'attribut //**xsi:type**="extern"//.
Noter que dans ce dernier cas, il est nécessaire de rajouter à l'élément //**include**// l'attribut //**parse**// à //"text"// afin d'indiquer qu'il s'agit de données textuelles.
La génération des règles à l'aide de macro s'effectue au moment de l'édition des liens. Si les règles conduisent à des erreurs alors elles ne sont pas créées.
===== Les patrons de règles =====
Les macros correspondent à des greffons ("//plugin//"), seul la macro définissant un patron de règles appelé //**template**// est native. Elle consiste simplement à définir un patron de règles à l'aide de variables. Ces variables renvoient aux colonnes d'un tableaux de valeurs dont chaque ligne correspond à une instance des règles décrites dans le patron.
Par exemple, voici un patron de règles suivi du fichier CSV auquel il fait référence :
hue,motor,output,credibility, credibility_tolerance,relevance
red, turn_left, 2, 1.0, INF, 0.1
blue, turn_right, 3, 0.5, 0.9, 0.2
red, turn_left, 2, 1.0, INF, 0.3
blue, turn_right, 3, 0.5, 0.9, 0.4
Soit le résultat final qui sera considéré lors de la compilation :
Un exemple concret sur l'emploi de patrons de règles se trouve dans la deuxième partie de tutoriel, plus précisément la [[tutoriel:proprietes_dynamiques#les_familles_de_classification|sous-section mettant en œuvre un apprentissage non-supervisé]].
===== Les formulations condensées de règles =====
La formulation de règles permet de nommer des prémisses et des conclusions puis de décrire des formules à l'aide de ces noms. Une formule peut se composer de trois partie, une partie inhibitrice, une partie excitatrice et la partie obligatoire regroupant les conclusions.
L'élément //**declarations**// contient la déclaration de tous les éléments prémisses et conclusions qui seront référencées dans les formules. L'élément //**formulas**// contient l'ensemble des formules décrites dans la macro.
Les éléments //**premise**// suivent la même syntaxe que celle se trouvant dans les règles hormis que l'attribut "//**inhibitor**//" est proscris et que l'attribut "**//name//**" est requis.
Les éléments //**conclusion**// suivent la même syntaxe que celle se trouvant dans les règles hormis que l'attribut "**//name//**" est requis et que les attributs "nbr_fitting" et "relevance" peuvent être présent afin d'initialiser la règle créée.
Il ne peut y avoir de nom de prémisse ou de conclusion identique.
La partie inhibitrice correspond à un ensemble de nom de prémisse séparer par l'opérateur booléen OU noté '+'. La fin d'une partie inhibitrice est indiqué par un point d'exclamation '!'. La partie inhibitrice sera appliqué à toute les règles issues de la formule. La partie excitatrice peut-être décrite avec les opérateurs booléen ET noté '.' et OU noté '+' et avec éventuellement des parenthèses. La partie décrivant les conclusions débute avec deux points ':' et elles sont séparées par une virgule.
Les commentaires sont précédé pour chaque ligne par "%%//%%".
Dans la macro **//formulaion//**, les noms des règles sont générés automatiquement.
L'exemple suivant exprime une formule qui conduira à la création de quatre règles, deux règles issues de la formule fois les deux lignes tableaux valeurs liés à la variable "//item_conclusion//":
item_conclusion
item1
item2
a.(b + c):d // exemple
Ce qui donne l'ensemble de règles nomo suivante :
===== La construction de règles à partir d'intervalles =====
La macro de discrétisation génère des règles à partir d'intervalles autrement dit détermine les valeurs et les tolérances permettant de respecter ces intervalles.
Par exemple, un ensemble perception "red", "green", "bleu" associé à une entrée d'une dimension comprise en 0 et 360 peut être défini comme suit : la limite entre "red" et "green" est 100, la limite entre "green" et "bleu" est 200.
La macro contient une règle prototype dont la composante ou les composantes définies par un intervalle possède un attribut //**interval**//. La valeur de l'élément //**information**// de la conclusion sera alors automatiquement ajouter ou modifier en fonction des intervalles. L’énoncé des intervalles s'effectue de manière croissante et commence et se termine obligatoirement par un item.
L'élément //**discretization**// possède l'attribut booléen //**center**//. Lorsque //**center**// vaut //true// alors les noyaux gaussiens sont calculé de telle sorte que la moyenne se trouve au centre de intervalle. Cette méthode oblige que les items soit tous différent.
Par exemple,
Soit les règles générées :
La couverture de ces règles de perception peut être illustré par le graphique suivant :
{{ :nomosdk:share:discretization_center_true.png?300 |}}
Lorsque l'attribut **//center//** vaut //false// le centrage n'est plus assuré en revanche la discrimination est davantage accentué de plus, il autorise à ce qu'un item puisse apparaître plusieurs fois. Toutefois, deux items ne peuvent se croiser plusieurs fois. Par exemple :
La couverture des règles de perception qui seront générées peut être illustrée par le graphique suivant :
{{ :nomosdk:share:discretization_center_false.png?300 |}}
A notez qu'aux limites, une incertitude demeure concernant l'appartenance des valeurs à un item. Toutefois, cela peut-être résolut facilement dans les cas des valeurs entière, auquel cas les limites pourront être simplement décalé d'une moitié d'unité en fonction du type de borne souhaitée.
Hormis que la seconde méthode de calcul (//**center**//="//false//") des noyaux gaussiens supporte l’emboîtement de noyaux gaussien, la discrimination entre les classes est plus forte comme l'illustre la comparaison entre les deux graphiques ci-dessous, à droite noyaux centrés, à gauche noyaux éventuellement non centrés :
{{:nomosdk:share:discretization_center_true_2.png?340|}}{{:nomosdk:share:discretization_center_false_2.png?340|}}
===== L'ajout de nouvelles macros =====
L'ajout d'un nouvel formalisme s'effectue en créant dans le répertoire "nomoSDK/macros" un répertoire avec pour nom celui de la nouvelle macro//"nom_de_la_macro"// respectant l'expression régulière [a-zA-Z]+[a-zA-Z0-9_]*
Ce nouveau répertoire doit contenir au minimum deux fichiers : //"nom_de_la_macro.dll"//, //"nom_de_la_macro.xsd"//
Le fichier //"nom_de_la_macro.xsd"// définit la grammaire du langage utilisé dans l'élément **//macro//** d'un programme nomo. L'espace de nom cible de la grammaire (//targetNamespace// et //xmlns//) doit suivre la forme //%%"http://www.nomoseed.org/nom_de_la_macro"%%//.
Le fichier //"nom_de_la_macro.dll"// correspond à la bibliothèque dynamique avec pour interface une fonction convention C dont le seul argument correspond au nom du fichier contenant le programme nomo à traiter :
void macroActualize(const char* file);
L'opération conduit à la création d'un fichier "macro.log" contenant les erreurs relevées.
Si aucune erreur s'est produite, autrement dit si le fichier "macro.log" est vide, alors le résultat de l'opération est sauvegardé dans //file//.
Le résultat doit fournir une ou plusieurs règles ou schèmes à la racine de la balise décrivant la macro soit l'élément portant le nom de "nom_de_la_macro" enfant de l'élément **//macro//**. Les règles peuvent contenir des variables. Par ailleurs, le tableau contenu dans l'élément //**csv**// peut être complété si besoin est car le ficher d'entrée aura auparavant résolut les éléments //**xinclude**//.
La transformation finale s'effectuera automatiquement via la macro //**template**//.