design intelligence
Table des matières

Tutoriel : la création de règles

L'objectif du tutoriel est d'illustrer les différentes manières de créer de règles selon les opérateurs employés.

La première partie se concentrera sur la création des règles de perception en montrant les quatre façons de sélectionner la prémisse d'entrée ainsi que la manière d'associer une règle de commande.

La deuxième partie portera sur la construction d’autres types règles. Les différents mécanismes permettant la sélection des prémisses seront détaillés ainsi que l'usage de l'opérateur servant à désigner la référence temporelle. Le cas particulier des règles de conception jumelées sera également abordé.

L’élaboration d’une structure perceptive sera l’objet de la troisième partie.

Enfin, la quatrième partie présentera une autopoièse sémiotique minimale, soit un ensemble de règles créant des règles qui créeront des règles et ainsi de suite en remplaçant les précédentes tombées dans l’oubli.

Créer une règle de perception simple

Dans cette partie, seul le cas de la création d'une règle de perception simple est traité, c'est-à-dire une règle avec une et une seule prémisse d'entrée.

Le procédé reste le même pour tous les exemples de cette partie : créer une règle consiste à identifier l'événement externe puis à s'en servir pour construire la prémisse d'entrée, la conclusion devra ensuite être créée.

Concernant les paramètres de la base de connaissances (knowledge_base), le maximum d'événements mémorisés (maximum_of_external_events et maximum_of_internal_events) sera de 10. La limite temporelle (time_span_limit) sera de 10 * 500 ms.

L'usine ajoutée au modèle

Le modèle “tutorial_4” a pour base “worldsquare”. Afin de définir le nombre de registre autre que celui servant à un évènement externe (minimum 1) ainsi que les opérateurs complexes (operator) et les références (scope), une structure usine (plant) est ajoutée.

<plant_structure others_registers_nbr="1">
  <input>
    <operator_type>
      <item name="create_premise_1" information_tolerance="0.1"/>
      <item name="create_premise_2" information_tolerance="0.3"/>
    </operator_type>
    <scope_type>
      <item name="hue"
            target_category="input"
            target_model="tutorial_4"
            target_type="hue"/>
    </scope_type>
  </input>
  <other>
    <operator_type>
      <item name="create_conclusion_1" relevance="0.5" fitting_nbr="2"/>
      <item name="create_conclusion_2" relevance="1.0" fitting_nbr="INF"/>
    </operator_type>
    <scope_type>
      <item name="perception"
            target_category="perception"
            target_model="tutorial_4"
            target_type="*"/>
    </scope_type>
  </other>
</plant_structure>

Les règles communes aux deux premiers exemples

Dans cet exemple, l'agent avance droit devant lui à chaque pas, le déclenchement de la phase d'affection pour la création de règle est enclenché dès le début.

Deux règles de perception préexistent, l'une détectant la teinte bleue, l'autre détectant une teinte inconnue.

Lorsqu'une perception survient alors qu’elle ne se trouvait pas à l'origine, celle-ci déclenchera la production d'un son vert.

Une anomalie provenant de la production de règles déclenchera un son rouge.

Ci-dessous les règles nomo qui répondent à cette spécification, à noter que la règle begin_affectation lançant la phase d'affectation ne sert qu'une fois puis est supprimée car sa pertinence initiale (relevance) vaut zéro.

<rule name="advance">
  <conclusion model="tutorial_4" category="command" type="motor">
    <information value="advance"/>
    <output value="2"/>
  </conclusion>
</rule>
<rule name="detect_anomaly">
  <premise model="plant" category="anomaly" type="anomaly">
    <information tolerance="INF"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="command" type="sound">
    <information value="red"/>
    <output value="0"/>
  </conclusion>
</rule>
<rule name="detect_new_perception">
  <premise model="tutorial_4" category="perception" type="hue" inhibitor="true">
    <information value="default" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <premise model="tutorial_4" category="perception" type="hue" inhibitor="true">
    <information value="blue" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <premise model="tutorial_4" category="perception" type="hue">
    <information tolerance="INF"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="command" type="sound">
    <information value="green"/>
    <output value="100"/>
  </conclusion>
</rule>
<rule name="hue_blue">
  <premise model="tutorial_4" category="input" type="hue">
    <information value="200" tolerance="1"/>
  </premise>
  <conclusion model="tutorial_4" category="perception" type="hue">
    <information value="blue"/>
  </conclusion>
</rule>
<rule name="hue_unknown">
  <premise model="tutorial_4" category="input" type="hue">
    <information tolerance="INF"/>
  </premise>
  <conclusion model="tutorial_4" category="perception" type="hue">
    <information value="default"/>
  </conclusion>
</rule>
<rule name="begin_affectation" relevance="0">
  <conclusion model="plant" category="transition" type="transition">
    <information value="begin_affectation"/>
  </conclusion>
</rule>

Avec une sélection directe

Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex1”.

Phase d'affectation

Les références sur les évènements externes ne peuvent être directement utilisées qu'avec l'opérateur « prendre celui-là » (get_there). L'utilisation des opérateurs « prendre le début » (get_first), « prendre le précédent » (get_before), « prendre le dernier » (get_last) provoquera la production d'une anomalie.

Dans notre exemple, l'objectif consiste à identifier et à copier le second évènement du type teinte (hue). Autrement dit, la référence temporelle du registre 00 (dédié aux événements externes) doit être produite en même temps que débute l'affection. La copie de l'évènement dans le registre 00 peut être invoquée en même temps que la référence par l'opérateur d'affectation « prendre celui-là » (get_there). Soit les deux règles suivantes :

<rule name="scope_hue" relevance="0">
  <conclusion model="tutorial_4" category="scope" type="register_00">
    <information value="hue"/>
  </conclusion>
</rule>
<rule name="copy_hue" relevance="0">
  <conclusion model="plant" category="operator" type="register_00">
    <information value="get_there"/>
  </conclusion>
</rule>

Au même moment, la dérivation d'une perception de type hue dans le registre 01 peut être entreprise avec l'opérateur « créer une perception retardée » (create_perception_forward). La copie de l'événement externe dans le registre 00 indique implicitement le type de la perception à dériver ainsi que la valeur de l'information par simple incrémentation de la valeur de l'information maximale pour ce type de perception. Soit la règle suivante :

<rule name="create_perception" relevance="0">
  <conclusion model="plant" category="operator" type="register_01">
    <information value="create_perception_forward"/>
  </conclusion>
</rule>

Avant d'aborder la phase de création des prémisses et après avoir dériver la perception, il reste à indiquer le repère temporel qui servira à la construction de la règle. Ici l'origine et le repère temporel se porte sur la perception créée, soit :

<rule name="target_reference">
  <premise model="plant" category="operator" type="register_01">
    <information value="create_perception_forward" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_01">
    <information value="transform_in_temporal_reference_and_origin"/>
  </conclusion>
</rule>

Phase de création des prémisses excitatrices

Une fois le repère temporel positionné, la phase de création de prémisses excitatrices peut commencer. Les opérateurs de création de prémisse peuvent être appliqués en même temps que le lancement de cette phase. Soit les deux règles suivantes :

<rule name="create_premise">
  <premise model="plant" category="operator" type="register_01">
    <information value="transform_in_temporal_reference_and_origin" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="operator" type="register_00">
    <information value="create_premise_1"/>
  </conclusion>
</rule>
<rule name="begin_excitation">
  <premise model="plant" category="operator" type="register_01">
    <information value="transform_in_temporal_reference_and_origin" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="transition" type="transition">
    <information value="begin_excitation"/>
  </conclusion>
</rule>

Phase de création de la conclusion

Puisque la règle à créer ne possède qu'une seule prémisse, dès que celle-ci est créée, la phase finale de création de conclusion peut être entreprise. Soit les deux règles suivantes :

<rule name="begin_finalization">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_excitation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="transition" type="transition">
    <information value="begin_finalization"/>
  </conclusion>
</rule>
<rule name="create_conclusion">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_excitation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="operator" type="register_01">
    <information value="create_conclusion_1"/>
  </conclusion>
</rule>

Dans le cas où une carte aurait la configuration suivante avec la première dalle de couleur rouge, le premier évènement rouge servirait à la création de la nouvelle perception et, la première utilisation de celle-ci aurait lieu à la seconde dalle rouge :

Le chronogramme du programme réalisé devient alors :

L'image de la mémoire événementielle au huitième coup d'horloge correspond au tableau suivant :

L'évènement hue de la catégorie scope du type register_00 désigne la référence sur laquelle l'opérateur get_there s'appliquera à la fin de la mise à jour de la mémoire évènementielle. Autrement dit, la référence temporelle correspond au dernier évènement de type hue depuis le coup d'horloge de son arrivée inclus, soit ici l'évènement d'entrée de valeur 100 du deuxième coup de l'horloge.

La règle créée correspond à la quinzième règle, le nouvel item de perception hue créé correspond au cinquième, soit, en langage nomo, la nouvelle règle pourrait s'écrire de la manière suivante :

<rule name="15" fitting_nbr="2">
  <premise model="tutorial_4" category="input" type="hue">
    <information value="100" tolerance="0.5"/>
  </premise>
  <conclusion model="tutorial_4" category="perception" type="hue">
    <information value="5"/>
  </conclusion>
</rule>

Avec une sélection indirecte

Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex2”.

Une sélection indirecte correspond à l'utilisation de la copie évènement dans un registre comme référence pour sélectionner un autre évènement.

Dans l'usine du modèle, le nombre de registre doit donc être augmenté de un, soit others_registers_nbr = 2.

Les illustrations suivantes représentent respectivement la carte utilisée et le chronogramme commun pour les quatre exemples :

L'évènement qui servira de repère sera un évènement de perception. Il sera identique dans les quatre exemples qui suivent. Il correspondra à la troisième perception soit le deuxième hue_unknown avant le quatrième pas de temps qui aura été déclenché par une teinte de 300 correspondant à un jaune orangé.

Les quatre exemples qui suivent diffèrent uniquement par la conclusion de la règle copy_hue définissant l'opérateur utilisé pour sélectionner un événement à partir du repère contenu dans un autre registre.

Après la présentation du programme, la différence de comportement entre les opérateurs sera explicitée et s’appuiera sur l'image de la mémoire évènementielle au quinzième coup d'horloge soit :

Phase d'affectation

Comme pour l'exemple précédent, l'affectation est déclenchée dès le début.

Le repère temporel qui permettra de sélectionner l'évènement d'entrée proviendra d'un registre différent que le registre 00 dédié aux entrées. La référence scope sert uniquement à désigner le type ou les types d'évènements d'entrée qui pourront être sélectionnés. Par conséquent, la désignation peut être introduit dés le lancement de la phase d'affectation, soit :

<rule name="scope_hue" relevance="0">
  <conclusion model="tutorial_4" category="scope" type="register_00">
    <information value="hue"/>
  </conclusion>
</rule>

Les deux règles permettant d'affecter le registre qui servira de repère (register_02) se calent sur l'évènement de transition begin_affectation après un pas de temps, soit :

<rule name="scope_mark">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_affectation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="1" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="scope" type="register_02">
    <information value="hue"/>
  </conclusion>
</rule>
<rule name="copy_mark">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_affectation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="1" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_02">
    <information value="get_there"/>
  </conclusion>
</rule>

Dans les quatre exemples, l'affectation du premier registre (register_00) s'effectuera au sixième pas de temps soit les règles suivantes, en se calant sur l'évènement de transition begin_affectation et dans le cas avec l'opérateur get_there.

<rule name="copy_hue">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_affectation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="3" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_00">
    <information value="get_there"/>
  </conclusion>
</rule>
<rule name="target_mark">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_affectation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="3" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_02">
    <information value="target"/>
  </conclusion>
</rule>

La création de la perception doit s'effectuer après l'affectation du registre 00 dédié aux entrées et qui devra ensuite être désigné comme repère temporel, soit les deux règles suivantes :

<rule name="create_perception" relevance="0">
  <premise model="plant" category="transition" type="transition">
    <information value="begin_affectation" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="4" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_01">
    <information value="create_perception_forward"/>
  </conclusion>
</rule>
<rule name="target_reference">
  <premise model="plant" category="operator" type="register_01">
    <information value="create_perception_forward" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="operator" type="register_01">
    <information value="transform_in_temporal_reference_and_origin"/>
  </conclusion>
</rule>

Phase de création des prémisses excitatrices

La phase de création des prémisses excitatrices correspond aux mêmes règles que dans l'exemple précédent :

<rule name="create_premise">
  <premise model="plant" category="operator" type="register_01">
    <information value="transform_in_temporal_reference_and_origin" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="operator" type="register_00">
    <information value="create_premise_1"/>
  </conclusion>
</rule>
<rule name="begin_finalization">
  <premise model="tutorial_4" category="operator" type="register_00">
    <information value="create_premise_1" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="transition" type="transition">
    <information value="begin_finalization"/>
  </conclusion>
</rule>

Phase de création de la conclusion

La phase de création de la conclusion correspond aux mêmes règles que dans l'exemple précédent :

<rule name="begin_finalization">
  <premise model="tutorial_4" category="operator" type="register_00">
    <information value="create_premise_1" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="plant" category="transition" type="transition">
    <information value="begin_finalization"/>
  </conclusion>
</rule>
<rule name="create_conclusion">
  <premise model="tutorial_4" category="operator" type="register_00">
    <information value="create_premise_1" tolerance="0"/>
    <credibility tolerance="INF"/>
    <timespan value="0" tolerance="0"/>
  </premise>
  <conclusion model="tutorial_4" category="operator" type="register_01">
    <information value="create_conclusion_1"/>
  </conclusion>
</rule>

Les quatre solutions

L'opérateur de sélection détermine quelle valeur d'entrée sera utilisée. Les quatre exemples restent circonscrits dans un cas simple compte tenu de la périodicité des évènements mais ils illustrent les quatre mécanismes existant pour sélectionner indirectement un évènement d'entrée.

Celui-là

Avec l'opérateur « prendre celui-là » (get_there), l'évènement sélectionné correspondra à l'évènement d'entrée le plus récent au moment de l'arrivé de l'évènement capturé par le registre register_02, soit ici de l'évènement hue_unknown arrivé au quatrième coup d'horloge.

Autrement dit, le plus récent évènement d'entrée de type hue depuis le quatrième coup d'horloge inclus correspond à celui arrivé au quatrième coup d'horloge.

Soit l'image de la mémoire évènementielle au quinzième coup de l'horloge :

Le premier de la série

Avec l'opérateur « prendre le début » (get_first), l'évènement sélectionné correspondra à l'évènement d'entrée le plus récent par rapport au premier évènement de la série d'évènements précédant, avec une information identique à l'évènement capturé par le registre register_02, soit ici à l'évènement hue_unknown arrivé au troisième coup d'horloge.

Si aucun évènement avec une même information n'avait précédé l'évènement capturé, alors c'est ce dernier qui aurait servi de repère.

Autrement dit, le plus récent évènement d'entrée de type hue depuis le premier évènement avec une information égale à hue_unknown depuis le quatrième coup d'horloge inclus correspond à celui arrivé au troisième coup d'horloge.

Soit l'image de la mémoire évènementielle au quinzième coup de l'horloge :

Le dernier de la série

Avec l'opérateur « prendre le dernier » (get_last), l'évènement sélectionné correspondra à l'évènement d'entrée le plus récent par rapport au dernier évènement de la série d'évènements suivant et avec une information identique à l'évènement capturé par le registre register_02, soit ici à l'évènement hue_unknown arrivé au cinquième coup d'horloge.

Si aucun évènement avec une même information n'avait suivi l'évènement capturé, alors c'est ce dernier qui aurait servi de repère.

Autrement dit, le plus récent évènement d'entrée de type hue depuis le dernier évènement avec une information égale à hue_unknown depuis le quatrième coup d'horloge inclus correspond à celui arrivé au cinquième coup d'horloge.

Soit l'image de la mémoire évènementielle au quinzième coup de l'horloge :

Celui précédant la série

Avec l'opérateur « prendre le précédent » (get_before), l'évènement sélectionné correspondra à l'évènement d'entrée le plus récent par rapport à l'évènement précédant la série d'évènements avec une information identique à l'évènement capturé par le registre register_02, soit ici à l'évènement hue_unknown arrivé au deuxième coup d'horloge.

Si aucun évènement avec une information différente n'avait précédé l'évènement capturé, alors une anomalie aurait été générée.

Autrement dit, le plus récent évènement d'entrée de type hue depuis l'événement hue_blue précédant le premier évènement avec une information égale à hue_unknown depuis le quatrième coup d'horloge inclus correspond à celui arrivé deuxième coup d'horloge.

Soit l'image de la mémoire évènementielle au quinzième coup de l'horloge :

Celui suivant la série

Avec l'opérateur « prendre le suivant » (get_after), l'évènement sélectionné correspondra à l'évènement d'entrée le plus récent par rapport à l'évènement suivant la série d'évènements avec une information identique à l'évènement capturé par le registre register_02, soit ici à l'évènement hue_unknown arrivé au sixième coup d'horloge.

Si aucun évènement avec une information différente n'avait précédé l'évènement capturé, alors une anomalie aurait été générée.

Autrement dit, le plus récent évènement d'entrée de type hue depuis l'événement hue_blue suivant le dernier évènement avec une information égale à hue_unknown depuis le quatrième coup d'horloge inclus correspond à celui arrivé au sixième coup d'horloge.

Soit l'image de la mémoire évènementielle au quinzième coup de l'horloge :

Avec une règle de commande associée

Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex3”.

La création d'une nouvelle commande s'appuie toujours sur la création d'une nouvelle perception. Ainsi, un type de commande, dont l'ensemble de définition est souhaité extensible, se trouve obligatoirement lié à un type de perception.

La création d'une nouvelle commande doit être précédé par la création de la nouvelle perception associée.

La création d'une nouvelle commande s'effectue à l'aide d'un des deux opérateurs suivant « créer une commande » (Create_Command) et « créer une commande retardée » (Create_Command_Forward) associés obligatoirement à l'opérateur « cibler » désignant l'item contenant la nouvelle perception.

L'objectif de l'exemple consiste à produire un son primal aléatoirement puis d'en créer une nouvelle règle perception suivie d'une règle de commande qui n'aura aucune condition.

Dans le monde de dalles, les types de commandes et de perception relatifs au son sont associés à sound. Par rapport au modèle de base, l'ensemble de définitions de la commande a été étendu pour inclure default afin de produire un son aléatoire :

<perceptive_structure name="sound">
  <command_type>
    <items>
      <item name="default"/>
      <item name="red"/>
      <item name="green"/>
      <item name="blue