Tutoriel : les propriétés logiques | nomoseed
design intelligence
Table des matières

Tutoriel : les propriétés logiques

L'objectif du tutoriel est de présenter les propriétés logiques élémentaires. Bien que ces propriétés puissent se combiner, la présentation de propriétés logiques se veut minimaliste afin d'illustrer au mieux les mécanismes du langage :

Le tutoriel sur les propriétés logiques repose sur l'utilisation du banc d'essais monde de dalles avec la carte tutorial_1.map. L'image ci-dessous illustre cet environnement avec la position initiale de l'agent :

Cet environnement sera modifié au cours des exemples. Tous les fichiers utilisés par ce tutoriel se trouvent dans le répertoire “nomoSDK/tutorial/tutorial_1”.

La configuration du moteur d'inférence (tutorial_1.eng) et celle de la base de connaissances (tutorial_1.bas) qui correspondent à celles par défaut dans nomoSDK sont également identiques dans toute cette partie du tutoriel.

Au cours de ce tutoriel un seul modèle sera utilisé. Un modèle définit le type de règles pouvant êtes exprimées ainsi que l'ensemble de définition de leur contenu. Le modèle du tutoriel (tutorial_1.mod) a pour base worldsquare.mod détaillé dans la présentation du monde de dalles. Ce modèle sera complété au fur et à mesure des exemples.

<model xmlns="http://www.nomoseed.org/model"
       xmlns:project="http://www.nomoseed.org/project"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:sdk="http://www.nomoseed.org/sdk"
       name="tutorial_1">
  <project:header>
    ...
  </project:header>
  <base>
    <xi:include href="basic_worldsquare.mod"/>
  </base>
  <definition>
 
   <!-- recopie de basic_worldsquare.mod avec les ajouts
        précisés au cours des exemples -->
 
</model>

Une description complète des différentes sortes de règles et de leur structure se trouve dans la partie base de connaissances de la documentation et leur traduction en langage nomo se trouve dans la partie hyponyme de la documentation.

Les aspects dynamiques n'étant pas abordés, toutes les règles auront un nombre d'ajustements infini (fitting_nbr=“INF”) et une pertinence maximale (relevance=“1”). Ces valeurs correspondent aux valeurs par défaut quand elles ne sont pas précisées dans les règles.

Logique d'ordre 0

La logique d'ordre 0 ou logique de prédicat constitue le principe élémentaire du système de règles : “si condition alors conclusion”. La condition est constituée d'une ou de plusieurs prémisses ou encore d'aucune prémisse.

Sans prémisse

Une règle possédant aucune prémisse est automatiquement éligible. Par exemple, le programme suivant consiste en une règle donnant l'ordre d'avancer à chaque pas. Aucune extension du modèle de base n'est requise. Le type de commande utilisé ici est déjà totalement défini dans le modèle de base worldsquare.mod.

La valeur de sortie output à 2, correspond à la commande motrice envoyée au composant extérieur gérant l'agent dans le monde dalle. La correspondance entre les items et les valeurs de commandes est représentée uniquement par les règles. Il ne peut y avoir deux règles de commande avec la même conclusion.

<program xmlns="http://www.nomoseed.org/program"
         xmlns:project="http://www.nomoseed.org/project"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:sdk="http://www.nomoseed.org/sdk"
         name="tutorial_1">
  <project:header>
  ...
  </project:header>
  <body>
    <models>
      <new instance="tutorial_1">
        <xi:include href="tutorial_1.mod" parse="xml"/>
      </new>
    </models>
    <scheme>
      	<rule name="M1">
          <conclusion model="tutorial_1" category="command" type="motor">
            <information value="advance"/>
            <output value="2"/>
          </conclusion>
      </rule>
    </scheme>
  </body>
</program>

Dans les paramètres de la base de connaissances tutorial_1.bas, le seuil de l'oubli timespan mis à la valeur auto conduit par déduction à la valeur 1ms, ce qui signifie que les faits ne restent qu'un pas dans la mémoire événementielle. Ainsi l'agent évolue dans l'environnement tutorial_1.map de la manière suivante:

  1. agent sur la dalle rouge, sélection de la règle M1, envoi de la commande d'avancer, introduction du fait advance ;
  2. exécution de l'action, agent sur la dalle verte, sélection de la règle M1, envoi de la commande d'avancer, oubli du précédent fait, introduction du fait advance;
  3. exécution de l'action, agent sur la dalle bleue, sélection de la règle M1, envoi de la commande d'avancer, oubli du précédent fait, introduction du fait advance ;
  4. échec de l'action motrice, agent sur la dalle bleue, sélection de la règle M1, envoi de la commande d'avancer, oubli du précédent fait, introduction du fait advance ;
  5. échec de l'action motrice, agent sur la dalle bleue, sélection de la règle M1, envoi de la commande d'avancer, oubli du précédent fait, introduction du fait advance ; …

La figure suivante correspond au chronogramme du programme, les pointillés signifient “conduit à” :

A ce stade, un autre cas peut être facilement illustré, celui où deux règles sélectionnables de même type ont des conditions identiques. La règle choisie correspond alors à la première règle rencontrée dans la base de règles. Par exemple, ajoutons une règle M2 similaire à M1 hormis qu'elle donne l'ordre de tourner à droite. Si la règle M2 est placée à la suite de M1 alors c'est M1 qui sera toujours sélectionnée ; à l'inverse dans le cas où M2 serait placée devant M1, ce serait cette dernière qui alors serait toujours sélectionnée.

Avec une prémisse

Une prémisse correspond aux critères de reconnaissance d'un événement d'un certain type. Le cas le plus général correspond à une prémisse acceptant tout événement d'un type donné quel que soit le contenu, la crédibilité, ou l'étiquette temporelle ; toutefois pour ce dernier, le signe doit être spécifié. Ici, seul le contenu a une tolérance nulle, les autres situations seront abordées progressivement dans les autres sections.

La perception

Dans l'exemple qui suit, un ensemble de trois règles sert à identifier la teinte des dalles. Ces trois règles sont regroupées dans un schème nommé hue_perceptions. L'organisation en schème est arbitraire, elle sert uniquement à organiser les règles du point de vue du programmeur.

Dans ce cadre, le modèle doit être complété de manière à étendre l'ensemble de définition de la structure perceptive hue dédiée à la perception de la teinte sur laquelle se trouve l'agent. L'ensemble des items disponible se réduit à red, green et blue. L'élément perceptive_structure avec le nom hue dans le modèle tutorial_1.mod devient :

<perceptive_structure name="hue">
  <items>
    <item name="red"/>
    <item name="green"/>
    <item name="blue"/>
  </items>
  <components>
    <component name="value"/>
  </components>
</perceptive_structure>

La tolérance associée à la valeur de la teinte attendue est nulle, c'est à dire que si aucune règle n'identifie exactement la teinte aucune règle de perception n'est déclenchée. La teinte d'une dalle est accessible par un clic gauche sur celle-ci. Dans l'environnement initial, les dalles rouges, vertes, bleues possèdent réciproquement une teinte de 0, 100 et 200. Une dalle avec une autre valeur que celles-ci ne provoquera aucune perception.

Le modèle complété, il suffit alors de recopier les règles ci-dessous dans le programme tutorial_1 :

<scheme name="hue_perceptions">
  <rule name="P1">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="0" tolerance="0" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="red"/>
    </conclusion>
  </rule>
  <rule name="P2">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="100" tolerance="0" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="green"/>
    </conclusion>
  </rule>
  <rule name="P3">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="200" tolerance="0" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="blue"/>
    </conclusion>
  </rule>
</scheme>

A noter, qu'il ne peut y avoir deux règles de perceptions avec une même conclusion.

A ce stade, le déroulement du programme n'affiche aucune différence avec le programme précédent, toutefois l'activité des règles est la suivante :

  1. agent sur la dalle rouge, sélection des règles M1 ainsi que P1, envoi de la commande d'avancer, introduction du fait de commande advance et du fait de perception red ;
  2. exécution de l'action, agent sur la dalle verte, sélection de la règle M1 ainsi que P2, envoi de la commande d'avancer, oubli des faits précédents, introduction du fait de commande advance et du fait de perception green ;
  3. exécution de l'action, agent sur la dalle bleue, sélection de la règle M1 ainsi que P3, envoi de la commande d'avancer, oubli des faits précédents, introduction du fait de commande advance et du fait de perception blue ;
  4. échec de l'action, agent sur la dalle bleue, sélection de la règle M1 ainsi que P3, envoi de la commande d'avancer et faire un son bleu, oubli des faits précédents, introduction du fait de commande advance et du fait de perception blue ; …

Soit le chronogramme suivant :

La perception et l'action

Afin de rendre compte de la perception, chaque perception peut être associée à un son qui sera symbolisé par un arc évanescent dont la teinte correspond à celle détectée.

Dans le modèle de base, le type de commande du son se trouve défini avec la perception du son car il renvoie à des phénomènes considérés de même nature. Dans ce cas, la structure perceptive impose que l'ensemble des perceptions contient l'ensemble des commandes.

Dans l'objectif de s'assurer une correspondance avec la perception de la teinte, l'ensemble des items disponibles reprend les valeurs red, green et bleu. L'élément perceptive_structure avec le nom sound dans le modèle tutorial_1.mod devient :

<perceptive_structure name="sound">
  <command_type>
    <items>
    <item name="red"/>
    <item name="green"/>
    <item name="bleu"/>
    </items>
  </command_type>
    <items>
      <item name="red"/>
      <item name="green"/>
      <item name="blue"/>
    </items>
  <components>
    <component name="value"/>
  </components>
</perceptive_structure>

Les règles de commande font le lien entre une perception d'une teinte et la commande d'un son. Ces règles de commande sont regroupées dans un schème nommé “sound_commands”.

<scheme name="sound_commands">
  <rule name="S1">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="red"/>
      <output value="0"/>
    </conclusion>
  </rule>
  <rule name="S2">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="green"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S3">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="blue" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="blue"/>
      <output value="200"/>
    </conclusion>
  </rule>
</scheme>

A noter, qu'il ne peut y avoir, comme pour les règles de perception, deux règles de commandes avec une même conclusion.

Pour toutes ces règles, l'étiquette temporelle n'étant pas précisée, elle est considérée par défaut comme une valeur positive avec une tolérance infinie. Le calcul du seuil de l'oubli reste donc au minimum, c'est à dire 1ms. La crédibilité n'étant pas définie, elle est par défaut à 1 avec une tolérance infinie.

En plaçant ces deux schèmes dans le premier programme comportant uniquement la règle M1 et en repositionnant l'agent en sa position initiale, le déroulement du programme s'effectue de la manière suivante :

  1. agent sur la dalle rouge, sélection des règles M1 ainsi que P1, envoi de la commande d'avancer, introduction du fait de commande advance et du fait de perception red ;
  2. exécution de l'action, agent sur la dalle verte, sélection de la règle M1 ainsi que P2 et S1, envoi de la commande d'avancer et faire un son vert, oubli des faits précédents, introduction du fait de commande advance, red et du fait de perception green ;
  3. exécution des actions, arc rouge, agent sur la dalle bleue, sélection de la règle M1 ainsi que P3 et S2, envoi de la commande d'avancer et faire un son vert, oubli des faits précédents, introduction du fait de commande advance, green et du fait de perception blue ;
  4. échec de l'action motrice, exécution de l'action sonore, arc vert, agent sur la dalle bleue, sélection de la règle M1 ainsi que P3 et S3, envoi de la commande d'avancer et faire un son bleu, oubli des faits précédents, introduction du fait de commande advance, blue et du fait de perception blue ;
  5. échec de l'action motrice, exécution de l'action sonore, arc bleu, agent sur la dalle bleue, sélection de la règle M1 ainsi que P3 et S3, envoi de la commande d'avancer et faire un son bleu, oubli des faits précédents, introduction du fait de commande advance, blue et du fait de perception blue ; …

Soit le chronogramme suivant :

Avec plusieurs prémisses

Le dernier exemple permet de lier une perception à une action, toutefois la production du signal “sonore” n'est pas synchrone avec la couleur de la dalle sur laquelle se trouve l'agent. Cela est dû au fait que la relation perception/action se décompose au minimum en deux règles alors que l'avance s'effectue à chaque pas de temps.

L'exemple suivant vise à synchroniser la production “sonore” et l'avance de l'agent, c'est à dire avancer tout en produisant un arc de même couleur que la dalle que l'agent vient de quitter.

La solution proposée utilise la notion de priorité évoquée à la fin du premier exemple et introduit la notion d'opérateur OU et ET. Avec les propriétés plus avancés présentées ultérieurement, des solutions plus élégantes pourront être imaginées.

L'opérateur OU

L'opérateur OU se traduit par l'existence de plusieurs règles ayant la même conclusion ; à noter que cet opérateur est interdit pour les perceptions et les commandes afin d'assurer leur intégrité en cas d'apprentissage. Les règles de commandes et de perceptions correspondent aux briques élémentaires qui peuvent servir à la définition de règles de conception représentant une perception ou une commande de plus haut niveau et qui peuvent modéliser l'opérateur OU.

Ici, l'emploi de cet opérateur sera illustré avec l'emploi de règles de conception.

Mais auparavant, pour synchroniser les règles, un nouveau type de conception doit être créé. L'introduction de ce nouveau type se traduit par le rajout dans le modèle tutorial_1.mod sous l'élément definition :

<conception_type name="control">
  <items>
    <item name="go"/>
    <item name="stop"/>
  </items>
</conception_type>

L'idée est que la production sonore et l'avance dépendent de l'évènement go et que la production de cet événement s'effectue en deux temps. Une perception déclenche une règle produisant un évènement stop, ce dernier conditionnant le déclenchement de l'évènement go.

Les règles servant à la synchronisation sont regroupées dans un nouveau schème :

<scheme name="control">
  <rule name="C0">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="stop" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="go"/>
    </conclusion>
  </rule>
  <rule name="C1">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="stop"/>
    </conclusion>
  </rule>
  <rule name="C3">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="blue" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="stop"/>
    </conclusion>
  </rule>
</scheme>

Les règles C1, C2, et C3 expriment un opérateur OU dans le sens où un événement stop est produit si il y a une perception red OU green OU blue.

A noter que la règle C0 est placée en premier dans le schème, de sorte que, en cas d'égale éligibilité avec les autres règles de son type, ce sera elle qui sera sélectionnée.

Par ailleurs, il aurait été possible de simplifier ces trois règles en une seule avec une tolérance “INF” comme suit. Autrement dit, la condition de cette règle aurait été remplie quelle que soit la perception établie. Mais dans ce cas, il n'y a pas stricte équivalence car cette seconde solution autorise l'ajout de nouvelles couleurs alors que l'autre oblige l'écriture d'une nouvelle règle le cas échéant.

<rule name="C1C2C3">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="INF"/>
  </premise>
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="stop"/>
  </conclusion>
</rule>

L'opérateur ET

L'opérateur ET consiste à mettre plusieurs prémisses dans une même règle. Ici, ce mécanisme permet de conditionner l'envoi d'une commande de son à une perception donnée ET à l'évènement go.

Le schème “sound_commands” devient :

<scheme name="sound_commands">
  <rule name="S1">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="red"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S2">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="green"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S3">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="blue" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="blue"/>
      <output value="200"/>
    </conclusion>
  </rule>
</scheme>

Il reste maintenant à modifier la règle M1 qui se déclenchait inconditionnellement à chaque pas de temps, en ajoutant une prémisse concernant l'événement go :

<rule name="M1">
  <premise model="tutorial_1" category="conception" type="control">
    <information value="go" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>

Le déroulement du nouveau programme s'effectue alors selon le chronogramme suivant :

Logique floue

La logique floue permet d'évaluer des valeurs non binaires. Par exemple, dans les programmes précédents, les tolérances sont strictement nulles : soit la valeur correspond à celle attendue, soit elle ne correspond pas. Une dalle qui aurait une teinte de valeur 1 ne conduirait à aucune perception alors qu'un rouge de teinte 0 et un rouge de teinte 1 sont très proches.

Dans le cadre du formalisme nomo, l'introduction de la logique floue provient de l'évaluation des valeurs continues constituant les vecteurs d'entrées et les indices temporels ainsi que les crédibilités. L'évaluation de ces valeurs continues s'effectue via un calcul d'une distance basé sur un noyau gaussien compris entre 0 et 1 ; 1 si identique, 0 si trop différent. Le résultat de l'évaluation de l'ensemble des prémisses de la règle sélectionnée correspond à la crédibilité associée à l'évènement produit par la conclusion.

Le premier exemple concerne l'évaluation de valeurs continues des entrées mais il est transposable aux autres sortes de valeurs continues. Le second exemple aborde l'utilisation de la notion de crédibilité.

Les valeurs continues

L'objectif de cet exemple est de rendre l'agent moins sensible à la variation de la teinte. Pour ce faire, une tolérance est rajoutée aux prémisses d'entrée des règles. Dans ce cadre, la tolérance représente l'écart type de la gaussienne caractérisant la prémisse.

Seules les règles de perceptions sont modifiées. Autrement dit, le déroulement reste le même sauf que la tolérance aux entrée est plus grande de sorte qu'une perception de vert produit par une entrée vert-jaune conduira à la production d'un arc vert. La tolérance passe ici de 0 à 7.

<scheme name="hue_perceptions">
  <rule name="P1">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="0" tolerance="7" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="red"/>
    </conclusion>
  </rule>
  <rule name="P2">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="100" tolerance="7" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="green"/>
    </conclusion>
  </rule>
  <rule name="P3">
    <premise model="tutorial_1" category="input" type="hue">
      <information value="200" tolerance="7" />
    </premise>
    <conclusion model="tutorial_1" category="perception" type="hue">
      <information value="blue"/>
    </conclusion>
  </rule>
</scheme>

Le changement de la teinte des dalles s'effectue par l’intermédiaire d'une fenêtre de paramétrage qui s'ouvre par un clic sur la dalle ou l'agent concerné.

Si une valeur d'entrée est trop éloignée de la moyenne par rapport à l'écart type, le score devient très proche de zéro de sorte qu'il est considéré comme nul lorsqu'il est inférieur à 1,17549E-38. Par exemple, une dalle avec une teinte de 300 correspondant à un rose ne permettra la sélection d'aucune perception.

Toutefois, si une perception est toujours souhaitée, une valeur par défaut peut être introduite en ajoutant un nouvel item dans le modèle de perception et en ajoutant une nouvelle règle avec une tolérance infinie.

<perceptive_structure name="hue">
  <items>
    <item name="red"/>
    <item name="green"/>
    <item name="blue"/>
    <item name="default"/>
  </items>
  <components>
    <component name="value"/>
  </components>
</perceptive_structure>
<rule name="P0">
  <premise model="tutorial_1" category="input" type="hue">
    <information value="0" tolerance="INF" />
  </premise>
  <conclusion model="tutorial_1" category="perception" type="hue">
    <information value="default"/>
  </conclusion>
</rule>

Les zones d'influences des règles perceptions peuvent se traduire par la visualisation des espérances, la règle sélectionnée étant celle qui maximise l'espérance. Le graphique suivant représente l’espérance des trois règle de perception en fonction de la teinte, où la couleur des courbes représente la couleur perçue et les droites noires en pointillés la perception P0 :

L'environnement de développement nomoSDK permet à l'aide de la macro de discrétisation de déterminer automatiquement les valeurs et les tolérances des règles uniquement en fonction des frontières entre les items.

La crédibilité d'un fait

Dans ce second exemple dédié à la logique floue, la production d'arc de couleur ne sera plus liée à la couleur perçue mais à la crédibilité avec laquelle elle est perçue. Si la perception est très crédible (proche de 1) alors un arc vert doit être produit, si la crédibilité est moyenne (proche de 0,5), un arc bleu et si elle est proche de zéro, un arc rouge.

Dans ce cas, une tolérance infinie est appliquée sur l'information.

Précédemment, la crédibilité et l'indice temporel n'apparaissaient pas explicitement dans les règles de sorte que ce sont leurs valeurs par défaut qui étaient appliquées : valeur à un avec une tolérance infinie. L'introduction de la crédibilité dans les prémisses oblige à expliciter également l'indice temporel. Les règles de production des arcs de couleurs deviennent :

<scheme name="sound_commands">
  <rule name="S1">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="INF"/>
      <credibility value="0" tolerance="0.707"/>
      <timespan value="1" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="red"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S2">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="INF"/>
      <credibility value="1" tolerance="0.707"/>
      <timespan value="1" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="green"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S3">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="blue" tolerance="INF"/>
      <credibility value="0.5" tolerance="0.707"/>
      <timespan value="1" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="blue"/>
      <output value="200"/>
    </conclusion>
  </rule>
</scheme>

Le graphique ci-dessous permet de visualiser les zones d'activation des règles de commande en fonction de la crédibilité du fait de perception, les zones colorées indiquent la règle sélectionnée :

Dans l’exemple précédent, l'égalité des tolérances implique que toutes les règles possèdent une spécificité identique de sorte que la règle sélectionnée correspond à celle dont la crédibilité est maximale. Mais ceci correspond à une situation particulière, à une situation d'équilibre.

En effet, plus une règle est spécialisée, plus elle devient prioritaire par rapport aux autres règles sur sa zone de sensibilité définie par ses prémisses. Ce qui signifie qu'à crédibilité égale une hiérarchie entre les règles est définie.

En modifiant les tolérances des règles de commandes avec respectivement les valeurs 0.361, 0.632, 0.707, les zones d'influences deviennent :

La crédibilité et la commande

Lorsque le vecteur de sortie associé à la commande est envoyé, la crédibilité l'est également. Le composant extérieur lié à cette commande peut utiliser ou non cette crédibilité.

Dans le cadre du banc d'essai monde de dalles, une crédibilité basse (>2/3) conduit à un retard d'un pas et une crédibilité très basse (>1/3) conduit à deux pas de retard.

Dans les exemples précédents, la crédibilité des commandes “sonores” était supérieure à 2/3 donc sans retard.

Dans l'exemple suivant, la crédibilité de la commande “sonore” dépendra de la crédibilité de la perception en s'appuyant sur la remarque sur la propagation des valeurs avec une tolérance sur la crédibilité de 0,1775. Seule la perception de rouge conduira à la production d'un arc rouge avec un retard dépendant de l'éloignement de la teinte de la dalle par rapport à un rouge de référence à 0, soit le programme minimal suivant :

<scheme>
  <rule name="M1">
    <conclusion model="tutorial_1" category="command" type="motor">
      <information value="advance"/>
      <output value="2"/>
    </conclusion>
  </rule>
  <rule name="P1">
    <premise category="input" type="hue" model="tutorial_1">
      <information value="0" tolerance="50"/>
    </premise>
    <conclusion category="perception" type="hue" model="tutorial_1">
      <information value="red"/>
    </conclusion>
  </rule>
  <rule name="S1">
    <premise category="input" type="hue" model="tutorial_1">
      <information value="red" tolerance="0"/>
      <credibility value="1" tolerance="0.1775"/>
      <timespan value="1" tolerance="INF"/>
    </premise>
    <conclusion category="perception" type="hue" model="tutorial_1">
      <information value="red"/>
    </conclusion>
  </rule>
</scheme>

Si la première dalle possède un rouge de teinte 5 alors la crédibilité de la perception rouge sera de 0,779. La crédibilité de la commande sera alors de 0,871. Dans ce cas, aucun retard ne sera induit.

Si la première dalle a un rouge de teinte 10 alors la crédibilité de la perception rouge sera de 0,368. La crédibilité de la commande sera alors de 0,324. Dans ce cas, la production de l'arc s'effectuera donc avec deux pas de retard.

Le chronogramme du second cas est alors le suivant :

Logique non-monotone

Une logique non-monotone permet que la relation de conséquence ne soit pas nécessairement monotone. Cela signifie qu'ajouter un fait à un ensemble de règles peut empêcher des déductions qui étaient précédemment possibles. On peut considérer que Titi l'oiseau vole tant que l'on ignore qu'il s'agit d'un pingouin.

Dans le formalisme nomo, la non-monotonie repose sur deux notions distinctes, la spécificité et l'inhibition.

La spécificité

La spécificité définit une hiérarchie entre les règles. Plus une règle est spécifique, plus elle est prioritaire sur les règles générales, et il n'y a qu'une règle sélectionnée par type.

L'exemple précédent sur la logique illustrait déjà le rôle de la spécificité mais pas dans le cadre de la non-monotonie qui confronte des règles comportant un nombre de prémisses différent.

En revanche, le mécanisme de non-monotonie peut s'illustrer en modifiant le schème “control”. En ajoutant une prémisse de la règle “C0”, la priorité de la règle ne provient plus de sa position dans le programme mais de sa condition :

<scheme name="control">
  <rule name="C0">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="stop" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="go"/>
    </conclusion>
  </rule>
  ...
</scheme>

Dans ce cas, la non-monotonie vient du fait que l'évènement de perception red qui déclenche la règle “C1” peut ne pas se produire si l'évènement stop est également présent à la faveur de la règle “C0”.

L'inhibition

L'inhibition constitue le second moyen pour modéliser de la logique non-monotone. La possibilité d'inhiber une règle vient de la présence d'une ou de plusieurs prémisses inhibitrices dont la crédibilité va se soustraire aux prémisses excitatrices.

Par rapport à l'exemple précédent dont l'objectif était de produire un arc de la couleur de dalle que l'agent venait de quitter, le mécanisme d'inhibition permet de simplifier les règles ainsi que le modèle et de raccourcir le nombre de pas.

En effet, dans une logique purement positive, il était nécessaire d'introduire de nouveau évènement pour synchroniser les règles. Dans une logique d'inhibition, les évènements peuvent également servir de verrou. Ainsi, la fréquence de sélection de la règle motrice peut être divisée par deux en ajoutant une prémisse inhibitrice sur un événement de commande motrice. La règle s'inhibera alors toute seule pendant un pas puis au delà d'un pas le fait commande sera oublié par la mémoire telle qu'elle est configurée.

Afin de synchroniser “M1” et les règles de production d'arc “S1”, “S2” et “S3” qui dépende d'une perception, une prémisse excitatrice de perception est ajoutée à la condition de la règle :

<rule name="M1">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="INF"/>
  </premise>
  <premise model="tutorial_1" category="command" type="motor" inhibitor="true">
    <information value="advance" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>

Les règles de production d'arc “S1”, “S2” et “S3” sont alors synchronisées de la même manière que la règle motrice “M1” :

<scheme name="sound_commands">
  <rule name="S1">
    <premise model="tutorial_1" category="command" type="motor" inhibitor="true">
      <information value="advance" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="red"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S2">
    <premise model="tutorial_1" category="command" type="motor" inhibitor="true">
      <information value="advance" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="green"/>
      <output value="100"/>
    </conclusion>
  </rule>
  <rule name="S3">
    <premise model="tutorial_1" category="command" type="motor" inhibitor="true">
      <information value="advance" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="blue" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="command" type="sound">
      <information value="blue"/>
      <output value="200"/>
    </conclusion>
  </rule>
</scheme>

Avec ce programme, les règles de conception dédiées à la synchronisation ne sont plus utiles ni même le type de conception défini dans le modèle.

Le chronogramme devient alors :

Logique temporelle

La logique temporelle nécessite une mémoire événementielle pouvant mémoriser plus d'un fait par type d'évènement (maximum_of_internal_event > 1) et un seuil d'oubli supérieur à la période de l'horloge ici à 500ms (time_span_limit > 500).

Pour les exemples qui suivent, une mémorisation de cinq faits est souhaitée sur une durée strictement inférieure à 3500ms ; toutefois, cinq événements consécutifs donnent une profondeur strictement inférieure à 2500ms.

Il faut donc modifier la configuration par défaut, soit le fichier tutorial_1.base :

<knowledge_base name="ma_base" 
                xmlns="http://www.nomoseed.org/base" >
 
  <header xmlns="http://www.nomoseed.org/project"> ... </header>
 
  <time_span_limit value="3500ms"/>
  <maximum_of_maximizations value="1"/>
  <maximum_of_internal_events value="5"/>
  <maximum_of_external_events value="1"/>
  <maximum_of_rules_by_type value="auto"/>
  <maximum_of_premises value="auto"/>
 
</knowledge_base>

A noter que ces changements entrainent le dysfonctionnement des programmes précédents où l'indice temporel des prémisses (de catégorie différent d'input) prend la valeur par défaut un avec une tolérance “INF”. En effet, dans ce cas, tous les évènements mémorisés possèdent la même valeur. Pour revenir à un fonctionnement normal, il faut mettre l'indice temporel à 0 avec une tolérance nulle afin de préciser que seuls les évènements venant d'arriver doivent être pris en compte.

La logique temporelle dépend de la gestion de la mémoire à laquelle les premiers exemples sont consacrés, suivi des exemples concernant la temporisation ainsi que les horloges, les séries temporelles et, les prédictions.

La gestion de la mémoire

La mémoire évènementielle correspond à un tore comportant au maximum maximum_of_internal_events évènements dont l'indice temporel est strictement inférieur à time_span_limit. Si la mémoire est pleine le nouvel évènement viendra écraser le plus ancien évènement.

Pour illustrer la gestion de la mémoire, un programme simple de trois règles pourra être décliné. La règle de commande “M1” sert uniquement à rendre concret l'évolution temporelle en faisant avancer l'agent à chaque pas. La règle de commande “S1” sert à identifier une situation de la mémoire événementielle du type de conception “control”. La règle de conception “C1” sert à alimenter la mémoire d'événements.

<rule name="C1">
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="go" delay="0"/>
  </conclusion>
</rule>
<rule name="S1">
  <premise model="tutorial_1" category="conception" type="control">
    <information value="go" tolerance="0"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="red"/>
    <output value="0"/>
  </conclusion>
</rule>
<rule name="M1">
  <conclusion model="tutorial_1" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>

Cette configuration initiale aura un fonctionnement identique quels que soient les paramètres utilisés puisque les prémisses détectent uniquement les évènements venant d'arriver et que le délai à la conclusion de “C1” est nul.

La règle “C1”, produisant des évènements à chaque pas, sature la mémoire au bout du cinquième pas, de sorte que la profondeur réelle de la mémoire est strictement inférieure à 2500ms.

Pour tester la profondeur de la mémoire, il suffit de modifier le timespan de la prémisse de “S1”.

Si timespan >= time_span_limit, cela produira une erreur à la compilation car une prémisse ne peut attendre un indice temporel supérieur ou égal au seuil de l'oubli time_span_limit défini dans les paramètres de la base de connaissances.

Si timespan >= 2500ms, la règle “C1” ne sera jamais appliquée car les nouveaux évènements écrasent les anciens.

Si timespan multiple de 500ms (puisque tolerance = 0) est strictement inférieur à 2500ms alors la règle se déclenchera dès qu'un premier évènement acquerra la durée désignée. Elle demeurera sélectionnée à chaque pas puisque le flot d'évènement ne cessera pas de fournir de nouveaux évènements.

Si le délai de la conclusion devient supérieur à zéro, dans ce cas la profondeur de la mémoire dépend de la capacité à résorber les délais. Par exemple si le delay = 500ms, la profondeur est simplement décalée d'autant.

Pour tester l'oubli non par l'écrasement d'évènements mais par leur dépassement du seuil, une solution consiste ici à diviser par deux la fréquence de sélection de “C1” en introduisant une prémisse inhibitrice.

<rule name="C1">
  <premise model="tutorial_1" category="conception" type="control" inhibitor="true">
    <information value="go" tolerance="0"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="go" delay="0"/>
  </conclusion>
</rule>

La temporisation et les horloges

La temporisation consiste à différer le déclenchement d'une ou de plusieurs règles. L'exemple ci-dessous consiste à différer l'avance de l'agent au lancement du programme. Pour introduire une telle latence, il existe principalement deux solutions.

La première consiste à attendre le front d'un flot d'évènements générés à chaque pas :

<rule name="M1">
  <premise model="tutorial_1" category="conception" type="control">
    <information value="go" tolerance="0"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="2000 ms" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>
<rule name="C0">
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="go"/>
  </conclusion>
</rule>

Dans ce cas, il faudra attendre le 2000/500 + 1 pas pour déclencher la règle “M1”. Mais cette méthode rend dépendant le programme à la fréquence d'interprétation ainsi que à la profondeur temporelle de la mémoire évènementielle.

La seconde méthode utilise la capacité des règles de conception à générer des évènements intentionnels, c'est-à-dire des évènements dont l'indice temporel est négatif. Une prémisse de conception discrimine obligatoirement soit les intentions (timespan<0), soit les évidences (timespan>=0) ; même lorsque la tolérance est infinie, d'où la nécessité de préciser un hypothétique indice temporel.

Contrairement aux évènements passés dont l'indice temporel est borné par le seuil de l'oubli, les évènements intentionnels peuvent arriver avec un indice temporel négatif infini (c'est-à-dire le temps maximal autorisé par l’implémentation).

La seconde solution utilise les évènements intentionnels comme un moyen de définir des états. La règle “C1”, qui se déclenchera uniquement au premier pas, place un évènement intentionnel dont la durée détermine la latence avant le déclenchement de la règle “C2” qui générera une intention permanente autorisant les déclenchements de “M1” :

<rule name="M1">
  <premise model="tutorial_1" category="conception" type="control" inhibitor="true">
    <information value="stop" tolerance="0"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="-1" tolerance="INF"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>
<rule name="C1">
  <premise model="tutorial_1" category="conception" type="control" inhibitor="true">
    <information value="go" tolerance="INF"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="-1" tolerance="INF"/>
  </premise>
  <premise model="tutorial_1" category="conception" type="control" inhibitor="true">
    <information value="stop" tolerance="0"/>
    <credibility value="1" tolerance="0"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="stop" delay="1000 ms"/>
  </conclusion>
</rule>
<rule name="C2">
  <premise model="tutorial_1" category="conception" type="control">
     <information value="stop" tolerance="0"/>
     <credibility value="1" tolerance="0"/>
     <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="conception" type="control">
    <information value="go" delay="MAX"/>
  </conclusion>
</rule>

Avec ce mécanisme, il devient possible de définir des horloges internes en définissant une règle servant à déclencher une première fois une règle provoquant ensuite périodiquement son propre déclenchement. Les horloges peuvent servir notamment pour synchroniser des règles. Par exemple, une solution pour synchroniser les règles “S1”, “S2”, “S3” et, “M1” de l'exemple précédent aurait pu être d'introduire une horloge comme suit :

<scheme name="control">
  <rule name="C0">
    <premise model="tutorial_1" category="perception" type="control">
      <information value="red" tolerance="INF"/>
    </premise>
    <premise model="tutorial_1" category="conception" type="control" inhibitor>
      <information value="go" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="go"/>
    </conclusion>
  </rule>
  <rule name="C1">
    <premise model="tutorial_1" category="conception" type="control">
      <information value="go" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="control">
      <information value="go" delay="500 ms"/>
    </conclusion>
  </rule>
</scheme>

À noter que l'ajout de prémisses peut transformer une horloge en “boucle tant que”.

Les séries temporelles

Dans cette section, quatre exemples élémentaires seront présentés afin d'illustrer les détections de séries temporelles d'événements. Tous ces exemples reprendront la règle motrice “M1” minimale ainsi que les règles de perception du second exemple de la logique d'ordre 0 soit :

<scheme>
  <rule name="M1">
    <conclusion model="tutorial_1" category="command" type="motor">
      <information value="advance"/>
      <output value="2"/>
    </conclusion>
  </rule>
  <scheme name="hue_perceptions">
    <rule name="P1">
      <premise model="tutorial_1" category="input" type="hue">
        <information value="0" tolerance="0" />
      </premise>
      <conclusion model="tutorial_1" category="perception" type="hue">
          <information value="red"/>
      </conclusion>
    </rule>
    <rule name="P2">
      <premise model="tutorial_1" category="input" type="hue">
        <information value="100" tolerance="0" />
      </premise>
      <conclusion model="tutorial_1" category="perception" type="hue">
        <information value="green"/>
      </conclusion>
    </rule>
    <rule name="P3">
      <premise model="tutorial_1" category="input" type="hue">
        <information value="200" tolerance="0" />
      </premise>
      <conclusion model="tutorial_1" category="perception" type="hue">
        <information value="blue"/>
      </conclusion>
    </rule>
  </scheme>
</scheme>

Cet ensemble de règles permet à l'agent d'avancer et de percevoir la teinte de la dalle à chaque pas.

Dans les exemples qui suivent, l'identification d'une série temporelle conduira à la production d'un arc de couleur bleue par la règle “S3”.

Une dalle rouge et une dalle verte

Ce premier exemple définit la condition de la règle “S3” comme la détection de deux perceptions de teinte, une rouge et une verte. Dans la condition détectant cet évènement composé, seule la teinte est spécifiée, pour la crédibilité et l'indice temporel, la tolérance est infinie. Toutefois, deux évènements de même type ne peuvent arriver simultanément dans la mémoire, de sorte qu'implicitement les faits de perception de la teinte qui répondront à la condition de “S3” seront forcément séparés dans le temps.

<rule name="S3">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="0" />
  </premise>
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="green" tolerance="0" />
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="blue"/>
    <output value="200"/>
  </conclusion>
</rule>

Dans l’environnement initial, la dalle rouge et la dalle verte se suivent de sorte que, une fois la dalle verte parcourue, l'agent produira un arc bleu tant qu'il existe au moins un fait red ET au moins un fait vert dans la mémoire évènementielle, autrement dit maximum_of_internal_events - 1 pas. Soit le chronogramme suivant :

Mais la condition de “S3” n'oblige pas la juxtaposition des faits ni un ordre particulier de perception de sorte que dans l'environnement suivant :

Le chronogramme devient :

Une dalle rouge puis une dalle verte

Dans le cas où l'ordre des faits serait important et que la détection doit s'effectuer uniquement lors de l'apparition des faits, alors la condition de la règle “S3” devient :

<rule name="S3">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="0" />
  </premise>
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="green" tolerance="0" />
    <credibility value="1" tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="blue"/>
    <output value="200"/>
  </conclusion>
</rule>
Une dalle rouge puis de suite une dalle verte

Si, par rapport à la règle précédemment définie, il est souhaité que les faits se suivent de suite alors, il suffit de mettre l'indice temporel de la prémisse capturant le fait red à la valeur correspondant au délai séparant les deux faits, soit ici 500ms.

<rule name="S3">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="0" />
    <credibility value="1" tolerance="INF"/>
    <timespan value="500 ms" tolerance="0"/>
  </premise>
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="green" tolerance="0" />
    <credibility value="1" tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="blue"/>
    <output value="200"/>
  </conclusion>
</rule>
Une dalle rouge puis plus ou moins de suite une dalle verte

Une tolérance non nulle sur l'indice temporel permet de détecter des séries temporelles avec une certaine variabilité sur le temps. Par exemple, la règle “S3” ci-dessous se déclenche lorsque le fait green apparaît juste après le fait red ou au pas suivant. En effet, au delà du pas suivant, le score de “S3” devient inférieur à 1,17549E-38 et par conséquent il est considéré comme nul.

<rule name="S3">
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="red" tolerance="0" />
    <credibility value="1" tolerance="INF"/>
    <timespan value="500 ms" tolerance="50"/>
  </premise>
  <premise model="tutorial_1" category="perception" type="hue">
    <information value="green" tolerance="0" />
    <credibility value="1" tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="blue"/>
    <output value="200"/>
  </conclusion>
</rule>

A noter que, dans le cas où plusieurs évènements pourraient correspondre à une ou plusieurs prémisses, la configuration choisie est celle qui maximise le score de la règle.

Les prédictions

Une prédiction définit un délai et un contenu ainsi qu'une évaluation dont la satisfaction dépend de la tolérance associée à ce délai et à la crédibilité de ce contenu.

Le formalisme nomo modélise les prédictions via une structure prédictive constituée de trois règles de trois types différents : prediction, landmark et check. Les règle de type landmark et de type prediction possèdent une condition identique. La règle de type landmark génère un évènement qui servira de point de comparaison avec l'évènement de prédiction généré par la règle de type prediction dans le cadre de l'évaluation de la règle de type check qui contrôle à la fois le contenu et le temps de l'évènement prédit.

Les prédictions portent uniquement sur les perceptions et les conceptions. Au sein du modèle “tutorial_1”, la structure prédictive concernant la perception “hue” est la suivante avec l'ajout de l'élément predicted_by dans la structure perceptive:

<predictive_structure name="hue">
  <items>
    <item name="red_prediction"/>
    <item name="green_prediction"/>
  </items>
</predictive_structure>
<perceptive_structure name="hue">
  <items>
    <item name="default"/>
    <item name="red"/>
    <item name="green"/>
    <item name="blue"/>
  </items>
  <predicted_by name="hue"/>
  <components>
    <component name="value"/>
  </components>
</perceptive_structure>

Dans l'exemple qui suit, le programme vise à prévoir une dalle rouge si l'agent perçoit une dalle verte. Dans le cas d'une avance à chaque, la prédiction stipule que la perception du rouge s'effectuera après 1500ms soit l'avance de trois cases.

L'introduction de la prémisse inhibitrice permet d'éviter la production d'évènements qui perturberaient la prédiction en cours. Toutefois, pour un même type, chaque prédiction différente est évaluée successivement et, une prédiction à plus court terme interrompra la prédiction en cours.

La fin de l'évaluation forcée ou normale conduit à la production d'un évènement check dont la crédibilité indique la qualité de la prédiction, aux extrêmes : 0 prédiction totalement incorrecte, 1 prédiction parfaite.

<scheme name="green_hue_prediction">
  <rule name="PR1">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="prediction" type="hue" inhibitor="true">
      <information value="red_prediction" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="-1" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="landmark" type="hue">
      <information value="red_prediction"/>
    </conclusion>
  </rule>
  <rule name="PR2">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="green" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="prediction" type="hue" inhibitor="true">
      <information value="red_prediction" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="-1" tolerance="INF"/>
    </premise>
    <conclusion model="tutorial_1" category="prediction" type="hue">
      <information value="red_prediction" delay="1500 ms"/>
    </conclusion>
  </rule>
  <rule name="PR3">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <premise model="tutorial_1" category="prediction" type="hue">
      <information value="red_prediction" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="-1" tolerance="INF"/>
    </premise>
    <premise model="tutorial_1" category="landmark" type="hue">
      <information value="red_prediction" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="1500 ms" tolerance="50"/>
    </premise>
    <conclusion model="tutorial_1" category="check" type="hue">
      <information value="red_prediction"/>
    </conclusion>
  </rule>
</scheme>

La visualisation de la réussite ou de l'échec de la prédiction pourra se faire en modifiant les règles S1 et S2 via la crédibilité de l'évènement de contrôle check :

<rule name="S1">
  <premise model="tutorial_1" category="check" type="hue">
    <information value="red_prediction" tolerance="0"/>
    <credibility value="0" tolerance="0.5"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="red"/>
    <output value="0"/>
  </conclusion>
</rule>
<rule name="S2">
  <premise model="tutorial_1" category="check" type="hue">
    <information value="red_prediction" tolerance="0"/>
    <credibility value="1" tolerance="0.5"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_1" category="command" type="sound">
    <information value="green"/>
    <output value="100"/>
  </conclusion>
</rule>

Avec cette dernière configuration de l'environnement, le chronogramme de prédiction est le suivant, en fond vert la durée de l'évaluation de la prédiction, (1500 + 50 x 1) / 500 = 3,1 arrondi au supérieur cela donne 4 pas :

Logique révisable

Une logique révisable permet de défaire un état ou un fait que l'on croyait acquis. En d'autres termes, cela revient à introduire la notion d'état ou de verrou.

Dans le formalisme nomo ce mécanisme peut être modélisé via les évènements intentionnels. En effet, l'arrivée d'une nouvelle intention élimine toutes celles dont le terme vient après cette dernière.

Par exemple, on souhaite rajouter à l'agent une variable interne mémorisant s'il a déjà perçu dernièrement une dalle rouge ou bleue. Pour cela un nouveau type de conception appelé remember comprenant deux items complète le modèle :

<conception_type name="remember">
  <items>
    <item name="red"/>
    <item name="bleu"/>
  </items>
</conception_type>

Le schème “management_remember” qui permet de mettre en place ou défaire un état red ou bleu. Lorsque l'agent est activé, aucune intention remember n'est présente. Dès que l'agent perçoit une teinte de la dalle, la règle sélectionnée correspond soit “RR1” soit “RB1”. Ces règles produisent un évènement sans délai de sorte que toutes les précédentes intentions sont éliminées. Elles autorisent ensuite la production d'évènements intentionnels avec un délai maximal via respectivement “RR2” et “RB2”.

L'état bleu ou red est représenté à la fois par un événement avec un indice temporel nul et par un évènement intentionnel.

<scheme name="management_remember">
  <rule name="RR1">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="red" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="remember">
      <information value="red" delay="0"/>
    </conclusion>
  </rule>
  <rule name="RR2">
    <premise model="tutorial_1" category="conception" type="remember">
      <information value="red" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="remember">
      <information value="red" delay="MAX"/>
    </conclusion>
  </rule>
  <rule name="RB1">
    <premise model="tutorial_1" category="perception" type="hue">
      <information value="bleu" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="remember">
      <information value="blue" delay="0"/>
    </conclusion>
  </rule>
  <rule name="RB2">
    <premise model="tutorial_1" category="conception" type="remember">
      <information value="bleu" tolerance="0"/>
      <credibility value="1" tolerance="INF"/>
      <timespan value="0" tolerance="0"/>
    </premise>
    <conclusion model="tutorial_1" category="conception" type="remember">
      <information value="bleu" delay="MAX"/>
    </conclusion>
  </rule>
</scheme>