nomoSDK : les macros | nomoseed
design intelligence
Table des matières

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 :

<sdk xmlns:sdk="http://www.nomoseed.org/sdk">
  <sdk:macro active="true" name="test_macro" xsi:type="sdk:template" >
    <sdk:csv select="2 to 3" xsi:type="sdk:extern">
      <xi:include href="test.csv" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude"/>
    </sdk:csv>
    <template select="2 to 3" xmlns="http://www.nomoseed.org/template" >
      <rule name="R" relevance="#relevance">
        <premise model="instmod" category="perception" type="hue">
          <information value="#hue" tolerance="0"/>
        </premise>
        <conclusion model="instmod" category="command" type="motor">
          <information value="#motor"/>
          <output value="#output"/>
        </conclusion>
      </rule>
    </template>
  <sdk:macro>
<sdk>
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 :

<scheme>
  <scheme name="test_macro">
    <rule name="R_2" relevance="0.2">
      <premise model="instmod" category="perception" type="hue">
        <information value="blue" tolerance="0"/>
      </premise>
      <conclusion model="instmod" category="command" type="motor">
        <information value="turn_right"/>
        <output value="3"/>
      </conclusion>
    </rule>
    <rule name="R_4" relevance="0.3">
      <premise model="instmod" category="perception" type="hue">
        <information value="red" tolerance="0"/>
      </premise>
      <conclusion model="instmod" category="command" type="motor">
        <information value="turn_left"/>
        <output value="2"/>
      </conclusion>
    </rule>
  </scheme>
</scheme>

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 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”:

<sdk:macro active="true" name="test_formulation" xsi:type="sdk:formulation">
  <sdk:csv xsi:type="sdk:embedded">
      item_conclusion
      item1
      item2
  </sdk:csv>
  <formulation xmlns="http://www.nomoseed.org/formulation">
    <declarations>
      <premise model="model_1" category="conception" type="c1" name="a">
        <information value="item1" tolerance="0"/>
      </premise>
      <premise model="model_1" category="conception" type="c2" name="b">
        <information value="item1" tolerance="0"/>
      </premise>
      <premise model="model_2" category="perception" type="p3" name="c">
        <information value="item1" tolerance="0"/>
        <credibility value="0.5" tolerance="0.7"/>
        <timespan value="0" tolerance="0"/>
      </premise>
      <conclusion model="tutorial_1" category="conception" type="c2" name="d">
        <information value="#item_conclusion"/>
      </conclusion>
    </declarations>
    <formulas>
      a.(b + c):d   // exemple
    </formulas>
  </formulation>
</sdk:macro>

Ce qui donne l'ensemble de règles nomo suivante :

<scheme>
  <scheme name="test_formulation">
    <rule name="id2309_1">
     <premise model="model_1" category="conception" type="c1">
       <information value="item1" tolerance="0"/>
     </premise>
     <premise model="model_1" category="conception" type="c2">
       <information value="item1" tolerance="0"/>
     </premise>
     <conclusion model="tutorial_1" category="conception" type="c2">
       <information value="item1"/>
     </conclusion>
    </rule >
    <rule name="id2310_1">
      <premise model="model_1" category="conception" type="c1">
        <information value="item1" tolerance="0"/>
      </premise>
      <premise model="model_2" category="perception" type="p3">
        <information value="item1" tolerance="0"/>
        <credibility value="0.5" tolerance="0.7"/>
        <timespan value="0" tolerance="0"/>
      </premise>
      <conclusion model="tutorial_1" category="conception" type="c2">
        <information value="item1"/>
      </conclusion>
    </rule >
    <rule name="id2309_2">
      <premise model="model_1" category="conception" type="c1">
        <information value="item1" tolerance="0"/>
      </premise>
      <premise model="model_1" category="conception" type="c2">
        <information value="item1" tolerance="0"/>
      </premise>
      <conclusion model="tutorial_1" category="conception" type="c2">
        <information value="item1"/>
      </conclusion>
    </rule >
    <rule name="id2310_2">
      <premise model="model_1" category="conception" type="c1">
      <information value="item1" tolerance="0"/>
      </premise>
      <premise model="model_2" category="perception" type="p3">
        <information value="item1" tolerance="0"/>
        <credibility value="0.5" tolerance="0.7"/>
        <timespan value="0" tolerance="0"/>
      </premise>
      <conclusion model="tutorial_1" category="conception" type="c2">
        <information value="item2"/>
      </conclusion>
    </rule >
  </scheme>
</scheme>

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,

<sdk xmlns:sdk="http://www.nomoseed.org/sdk">
  <sdk:macro active="true" name="test_discretization" xsi:type="sdk:discretization">
    <discretization xmlns="http://www.nomoseed.org/discretization" center="true">
      <rule name="rule" fitting_nbr="0" relevance="0.9">
        <premise model="model_1" category="input" type="hue">
          <information interval="red 100 green 200 bleu"/>
        </premise>
        <conclusion model="model_1" category="perception" type="hue"/>
      </rule>
    </discretization>
  </sdk:macro>
</sdk>

Soit les règles générées :

<scheme name="test1">
  <rule name="rule_1" fitting_nbr="0" relevance="0.9">
    <premise model="tutorial_1" category="input" type="hue">
      <information tolerance="5.0000000E+01" value="5.0000000E+01"/>
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="red"/>
    </conclusion>
  </rule>
  <rule name="rule_2" fitting_nbr="0" relevance="0.9">
    <premise model="tutorial_1" category="input" type="hue">
      <information tolerance="5.0000000E+01" value="1.5000000E+02"/>
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="green"/>
    </conclusion>
  </rule>
  <rule name="rule_3" fitting_nbr="0" relevance="0.9">
    <premise model="tutorial_1" category="input" type="hue">
      <information tolerance="5.0000000E+01" value="2.5000000E+02"/>
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="bleu"/>
    </conclusion>
  </rule>
</scheme>

La couverture de ces règles de perception peut être illustré par le graphique suivant :

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 :

<sdk xmlns:sdk="http://www.nomoseed.org/sdk">
  <sdk:macro active="true" name="test_discretization" xsi:type="sdk:discretization">
    <discretization xmlns="http://www.nomoseed.org/discretization" center="true">
      <rule name="rule" fitting_nbr="0" relevance="0.9">
        <premise model="model_1" category="input" type="hue">
          <information interval="red 100 green 200 bleu 300 red"/>
        </premise>
        <conclusion model="model_1" category="perception" type="hue"/>
      </rule>
    </discretization>
  </sdk:macro>
</sdk>

La couverture des règles de perception qui seront générées peut être illustrée par le graphique suivant :

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 :

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.