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"/> </items> </command_type> <items> <item name="default"/> <item name="red"/> <item name="green"/> <item name="blue"/> </items> <components> <component name="value"/> </components> </perceptive_structure>
De même, dans l'usine (plant_structure) contenue dans le modèle, l'item sound est rajouté pour la sélection de la référence :
<plant_structure others_registers_nbr="2"> <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_type="hue" target_model="tutorial_4" /> <item name="sound" target_category="input" target_type="sound" target_model="tutorial_4" /> </scope_type> </input> ... </plant_structure>
Pour générer un son aléatoire, il est nécessaire de définir une perception par défaut. Le couple de règles qui pourra être supprimé après le premier coup d'horloge devient :
<rule name="sound_unknown" relevance="0"> <premise model="tutorial_4" category="input" type="sound"> <information tolerance="INF"/> </premise> <conclusion model="tutorial_4" category="perception" type="sound"> <information value="default"/> </conclusion> </rule> <rule name="sound_primal" relevance="0"> <conclusion model="tutorial_4" category="command" type="sound"> <information value="default"/> <output value="200"/> </conclusion> </rule>
L’enchaînement des règles s'appuie ici uniquement sur l'indice temporel de l'événement de commande initiale. La création de la règle de perception suit en tout point la solution du premier exemple, les règles correspondant à la création de la commande se déroulent après le déclenchement de create_conclusion :
<rule name="begin_affectation_2"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="4" tolerance="0"/> </premise> <conclusion model="plant" category="transition" type="transition"> <information value="begin_affectation"/> </conclusion> </rule> <rule name="create_command"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="4" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_02"> <information value="create_command"/> </conclusion> </rule> <rule name="target_perception"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="4" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_01"> <information value="target"/> </conclusion> </rule> <rule name="target_reference_2"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="5" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_02"> <information value="transform_in_temporal_reference_and_origin"/> </conclusion> </rule> <rule name="begin_excitation_2"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="7" tolerance="0"/> </premise> <conclusion model="plant" category="transition" type="transition"> <information value="begin_excitation"/> </conclusion> </rule> <rule name="begin_finalization_2"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="7" tolerance="0"/> </premise> <conclusion model="plant" category="transition" type="transition"> <information value="begin_finalization"/> </conclusion> </rule> <rule name="create_conclusion_2"> <premise model="tutorial_4" category="command" type="sound"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="7" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="operator" type="register_02"> <information value="create_conclusion_1"/> </conclusion> </rule>
Soit l'image de la mémoire évènementielle au douzième coup d'horloge :
Créer une règle autre que de perception
La création de règles autres que des perceptions ou des commandes autorise une latitude plus large sur les emplois des opérateurs d'affectation de manière directe ainsi que ceux désignant la référence temporelle.
Mais il reste impossible de réaliser des règles non causales.
La première partie s'attachera à illustrer l'utilisation des repères temporels, les exemples portent sur des règles de conception qui autorisent un délai dans les conclusions et, par conséquent offrent plus de possibilités.
La deuxième partie proposera une manière d'utiliser la création de règles jumelées en proposant un mécanisme d'inhibition a posteriori.
La troisième et dernière partie montrera la création d'une structure prédictive composée de trois règles.
Les repères temporels
Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex4”.
Pour cette série d'exemples, le modèle sera complété par un nouveau type de conception appelé concept_a comme suit :
<conception_type name="concept_a"> <items> <item name="a"/> </items> </conception_type>
La règle de détection d'un événement d'un type concept_a est alors :
<rule name="detect_conception"> <premise model="tutorial_4" category="conception" type="concept_a"> <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>
La règle d'avance systématique dans les exemples précédents est conservée, de même que celle de détection d'anomalies, celle de perception et celle de transition.
L'environnement se trouve être le même que celui du dernier exemple :
Les exemples suivant reposent sur l'objectif de concevoir une règle de conception de type concept_a ayant pour condition excitatrice une perception. Ci-dessous en détail le premier exemple.
L'affectation
Une premier solution consiste à choisir le même évènement que dans les exemples précédents dans le regiter_01et de placer une référence au même moment avec le type concept_a dans l'autre registre (register_02), soit dans un premier temps la capture des évènements :
<rule name="scope_hue"> <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_01"> <information value="perception"/> </conclusion> </rule> <rule name="scope_concept_a"> <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="concept_a"/> </conclusion> </rule>
Suivi de leur affectation :
<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_01"> <information value="get_first"/> </conclusion> </rule> <rule name="create_conception"> <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_02"> <information value="create_conception"/> </conclusion> </rule>
La règle target_reference dédiée au placement du repère temporel transform_in_temporal_reference identique aux exemples précédents :
<rule name="target_reference"> <premise model="plant" category="operator" type="register_02"> <information value="create_conception" 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>
La condition et la conclusion
La condition et la conclusion s'effectuent de la même manière dans tous les cas suivants :
<rule name="begin_excitation"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="6" tolerance="0"/> </premise> <conclusion model="plant" category="transition" type="transition"> <information value="begin_excitation"/> </conclusion> </rule> <rule name="create_premise"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="6" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="operator" type="register_01"> <information value="create_premise_1"/> </conclusion> </rule> <rule name="begin_finalization"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="7" 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_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="7" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="operator" type="register_02"> <information value="create_conclusion_1"/> </conclusion> </rule>
Avec pour rappel, l'opérateur create_premise_1 définit comme suit dans le modèle :
<plant_structure others_registers_nbr="2"> ... <other> <operator_type> <item name="create_premise_1" information_tolerance="0" credibility_tolerance="INF" timespan_tolerance="0"/> ... </operator_type> </other> </plant_structure>
Analyse
L'état de la mémoire évènementielle au quatorzième coup d'horloge correspond au tableau suivant :
Dans cet exemple, les références sont capturées en même temps avec perception et concept_a. La référence du registre register_02 a un contenu vide puisqu'il n'a pas d'évènement correspondant mais le temps (au quatrième coup d'horloge) et le type sont notés. Ces dernières informations serviront lors de la création d'un concept.
L'opérateur get_before permet de capturer l'évènement de perception hue arrivé au deuxième coup d'horloge soit blue.
L'opérateur create_conception créée un nouvel item de conception de type concept_a.
Ainsi, une durée de trois coups d'horloge sépare l'évènement de perception capturé et le concept nouvellement créé.
Le registre register_01 est transformé en référence et origine temporelle pour la construction de la règle. Cela signifie que l'indice temporel (dt) de l'évènement au moment de son arrivée, et non de sa capture, correspondra au temps de référence pour la détermination des indices temporels pour les autres prémisses ou la conclusion.
Dans cet exemple, la description de la règle créée se présente comme suit :
<rule name="new_concept_a_rule"> <premise model="plant" category="perception" type="hue"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="1" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="conception" type="concept_a"> <information value="new_concept_a_item" delay="1"/> </conclusion> </rule>
Cela explique le retard induit dans la conclusion et qui apparaît dans l'image de la mémoire évènementielle ci-dessus.
Variantes
Sur l'opérateur de création d'un concept
Dans le cas où la conception ne doit pas comporter de retard dans la conclusion en gardant la référence temporelle sur la perception, il faut retarder artificiellement le temps d'arrivée de la conception correspondant au temps d'arrivée de la désignation concept_a de type regiter_02 de catégorie scope. Un retard d'un pas peut être produit par l'emploi de l'opérateur backward :
<rule name="backward_concept_a"> <premise model="plant" category="operator" type="register_02"> <information value="create_conception" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="0" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_02"> <information value="backward"/> </conclusion> </rule>
Le décalage induit par cet opérateur supprimera le délai de la conclusion, comme suit :
<rule name="new_concept_a_rule"> <premise model="plant" category="perception" type="hue"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="1" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="conception" type="concept_a"> <information value="new_concept_a_item"/> </conclusion> </rule>
Dans le cas où l'on ne souhaiterait plus créer une nouvelle conception mais simplement en recopier une produite par une règle initiale avec une pertinence nulle (relevance=“0”) de sorte qu'elle s'élimine dès le premier coup d'horloge.
Cette seconde variante se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex5”.
<rule name="first_concept_a" relevance="0"> <conclusion model="tutorial_4" category="conception" type="concept_a"> <information value="a" delay="2"/> </conclusion> </rule>
La règle plaçant l'opérateur « créer un concept » (create_conception)est remplacée par une règle de copie comme suit :
<rule name="copy_concept_a"> <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_02"> <information value="get_there"/> </conclusion> </rule>
Ce montage permettra d'obtenir une règle de la forme identique à l'exemple initial.
Sur l'opérateur de repère temporel
Dans le cas où l'opérateur de repère temporel devient l'opérateur transform_in_temporal_reference au lieu de transform_in_temporal_reference_and_origin, le délai de la conclusion deviendrai positif (0 + un pas temps du fait que la conclusion ne correspond pas au repère temporel).
Une autre manière de faire consiste à appliquer le repère temporel à la conclusion, dans ce cas la règle créée aura la forme suivante :
<rule name="copy_concept_a"> <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_02"> <information value="get_there"/> </conclusion> </rule>
Une autre manière encore consiste à mettre l'indice temporel de la prémisse à zéro et d'allonger le délai de la conclusion dans le temps, de telle sorte que cela supprime le délai, comme suit :
<rule name="new_concept_a_rule"> <premise model="plant" category="perception" type="hue"> <information value="default" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="1" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="conception" type="concept_a"> <information value="new_concept_a_item" delay="0"/> </conclusion> </rule>
D'autres combinaisons restent possibles en usant des opérateurs backward, forward et same_time (avec target), ou en décalant la désignation concept_a. Ces variantes peuvent être explorées dans “nomoSDK/tutorial/turorial_4/ex6”.
Le cas des règles jumelées
Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex7”.
Lorsqu'un type est jumelé à un type de conception, il est possible de créer un évènement de type conception correspondant à l'évènement du type jumelé.
Par exemple, dans le cas où le type de perception hue possède un type de conception jumeau, si l'évènement de perception red était capturé par un registre, alors, il deviendrait possible via l'opérateur « créer un jumeau » (create_twin) de dériver l'évènement idoine du type de conception jumeau dans un autre registre. Plus précisément, un opérateur « cibler » (target) devrait être appliqué au registre ayant capturé la perception et l'opérateur « créer un jumeau » (create_twin) appliqué à un autre registre qui contiendra l'évènement jumeau.
L’intérêt d'un tel mécanisme réside, par exemple, dans la possibilité de créer a posteriori des règles inhibitrices en intégrant, dans la règle qui pourra être inhibée, une prémisse inhibitrice de même valeur que la conclusion mais du type de conception jumeau :
Une perception blue entraîne la production d'un son blue après un pas de temps. Dans l'objectif d'apprendre à ne pas produire ce son bleu à la suite d'une perception bleue, une règle devra être créée qui aura pour conséquence d'inhiber la règle produisant ce son.
Un tel scénario implique l'introduction d'un jumeau dans le type de commande se trouvant ici dans la structure perceptive sound du modèle, soit :
<perceptive_structure name="sound"> <command_type> <conception_type name="sound"> <items> <item name="red"/> <item name="green"/> <item name="blue"/> </items> </conception_type> <items> <item name="red"/> <item name="green"/> <item name="blue"/> </items> </command_type> <items> <item name="default"/> <item name="red"/> <item name="green"/> <item name="blue"/> </items> <components> <component name="value"/> </components> </perceptive_structure>
Les règles initiales, sans les règles dédiées à la création de règles, correspondent aux règles suivantes :
<rule name="detect_hue_blue"> <premise model="tutorial_4" category="conception" type="sound" 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 value="blue" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="1" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="command" type="sound"> <information value="blue"/> <output value="200"/> </conclusion> </rule> <rule name="hue_blue"> <premise model="tutorial_4" category="input" type="hue"> <information value="200" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="perception" type="hue"> <information value="blue"/> </conclusion> </rule>
La phase d'affectation est lancée dès la détection d'une perception bleue et d'un son séparé de deux pas de temps et sera suivie par quatre règles permettant de capturer l'évènement de perception et l'évènement de commande :
<rule name="begin_affectation"> <premise model="tutorial_4" category="perception" type="hue"> <information tolerance="INF"/> <credibility tolerance="INF"/> <timespan value="2" tolerance="0"/> </premise> <premise model="tutorial_4" category="command" type="sound"> <information tolerance="INF"/> <credibility tolerance="INF"/> <timespan value="0" tolerance="0"/> </premise> <conclusion model="plant" category="transition" type="transition"> <information value="begin_affectation"/> </conclusion> </rule> <rule name="scope_hue"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="0" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="scope" type="register_01"> <information value="hue"/> </conclusion> </rule> <rule name="scope_sound"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="0" tolerance="0"/> </premise> <conclusion model="tutorial_4" category="scope" type="register_02"> <information value="sound"/> </conclusion> </rule> <rule name="copy_hue"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="0" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_01"> <information value="get_first"/> </conclusion> </rule> <rule name="copy_sound"> <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>
La création de la conception jumelée s'effectue via l'opérateur create_twin et l'opérateur target sur le troisième registre :
<rule name="create_twin"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="2" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_03"> <information value="create_twin"/> </conclusion> </rule> <rule name="target_twin"> <premise model="plant" category="transition" type="transition"> <information value="begin_affectation" tolerance="0"/> <credibility tolerance="INF"/> <timespan value="2" tolerance="0"/> </premise> <conclusion model="plant" category="operator" type="register_02"> <information value="target"/> </conclusion> </rule> <code> Il reste alors à corriger la référence temporelle du concept créé et à placer le repère temporel de la règle : <code xml> <rule name="target_reference"> <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_01"> <information value="transform_in_temporal_reference_and_origin"/> </conclusion> </rule> <rule name="backward_twin"> <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_03"> <information value="backward"/> </conclusion> </rule>
Les règles restantes pour les phases constituant les prémisses et la conclusion suivent la même logique que dans les exemples précédents.
En considérant la carte suivante, la première dalle étant bleue conduira à la production d'un son bleu mais suite la création de la règle, la seconde dalle bleue ne conduira à aucun son.
D'autres manières de synchroniser les règles auraient été possibles. Par ailleurs, l'ensemble des règles fonctionne bien pour cet environnement mais ne gère pas, par exemple, l’enchaînement successif de dalles bleues au début.
Créer une structure prédictive avec rétribution
Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex8”.
L'exemple suivant propose de créer une structure prédictive avec rétribution lorsqu'une perception de teinte apparaît et qu'aucune création de règle ou prédiction n'est en cours.
L'ensemble des règles initiales proposées dans cet exemple ne couvre pas tous les cas de figure mais illustre l'enchainement des différentes phases pour concevoir les règles et surtout l'utilisation des opérateurs servant à la manipulation des indices temporels des évènements recopiés.
L'ensemble des règles initiales fonctionne avec l'environnement suivant où une règle de son (detect_reward) signalant la présence d'une récompense sera déclenchée au trente et unième pas de temps :
Grâce à la journalisation, la liste des activations des règles peut se visualiser sous la forme d'un tableau avec la requête SQL suivante :
SELECT DISTINCT log.time, rule.name AS rule_name, type.name AS type_name, category, hue, luminance, saturation FROM log NATURAL JOIN rule JOIN type ON type.type_id = rule.type_id ORDER BY log.time
Une autre manière de représenter les activations consiste à utiliser la requête SQL ci-dessous avec une visualisation graphique.
SELECT DISTINCT log.time, rule_id, hue, luminance, saturation FROM log NATURAL JOIN rule JOIN type ON type.type_id = rule.type_id ORDER BY log.time
Le graphique ci-dessous montre le résultat obtenu annoté des règles participants à l'activation de la structure prédictive créée :
Exemple d'une autopoièse sémiotique minimale
Cet exemple se trouve dans répertoire “nomoSDK/tutorial/tutorial_4/ex9”.
Une autopoièse sémiotique consiste en un ensemble de règles produisant continuellement des règles à partir de leur propre activité des règles et permettant ainsi de maintenir de ce processus malgré une élimination continue des règles.
Une autopoièse sémiotique minimale peut être considérée comme un ensemble de règles exécutant un cycle de création de règles reproduisant strictement l'activité de la mémoire évènementielle qui permet cette production.
Les règles produites peuvent être différentes des règles initiales dès lors qu'elles produisent des évènements qui permettront une nouvelle génération.
Le tableau ci-dessous représente l'état de la mémoire évènementielle au douzième coup d'horloge. Les trois premiers évènements proviennent de trois règles initiales sans condition et avec une pertinence nulle donc, elles seront éliminées juste après leur sélection. Ici un cycle de production s'effectue en quatre coups d'horloge. Le premier cycle n'est pas complet mais permet la production du suivant avec les autres règles initiales.
Sur un cycle de production, quatre règles sont produites. La prémisse qui sert à tous les règles produites est capturée par la désignation (scope) transition. Les conclusions proviennent de la capture de tout évènement quelque soit le type arrivant en même temps que la désignation all du registre idoine. Soit, la définition des opérateurs et désignateurs :
<plant_structure others_registers_nbr="5"> <input> <operator_type> </operator_type> <scope_type> </scope_type> </input> <other> <operator_type> <item name="create_premise"> <premise> <information tolerance="0"/> <credibility tolerance="INF"/> <timespan tolerance="0"/> </premise> </item> <item name="create_conclusion"> <conclusion relevance="0.999" fitting_nbr="INF"/> </item> </operator_type> <scope_type> <item name="transition"> <target category="transition" model="plant" type="transition"/> </item> <item name="all"> <target category="*" model="*" type="*"/> </item> </scope_type> </other> </plant_structure>
Aucun repère temporel n'étant désigné, chaque conclusion se trouve être le repère et l'origine temporelle lors de sa construction. Ainsi, l'indice temporel de la prémisse se trouve être différent pour chaque règle crées dans un même cycle. A noter que la prémisse repose toujours (sauf pour le premier cycle) sur l'évènement begin_affectation du cycle précédant capturé par l'opérateur get_same.
En considérant une taille de la mémoire à long terme illimitée, un seuil d'oubli nul et en faisant abstraction de la particularité du premier cycle, la probabilité d'obtenir un jeu de règle capable de reproduire cet enchainement d'évènement correspond au produit des probabilités que chaque désignation capture au moins une fois chaque évènement concomitant au bout de cycles avec puisque le nombre maximum d'évènements concomitants est de 6, soit :
Comme l'illustre le graphique suivant, plus le nombre de cycle augmente, plus la probabilité d'avoir reproduit un ensemble de règles générant tous les évènements tend vers 1, par exemple à partir de 20 cycles soit 80 coups d'horloge, la probabilité atteint environ 0,945.
Ainsi, en posant un taux d'enchère nul mais avec un taux de taxe de 0,1, le seuil de l'oubli est choisi de façon à ce que les règles initiales avec une pertinence de 0,9 perdurent jusqu'au quatre vingt unième coup d'horloge, soit 0,0028.
En posant pour les nouvelles règles une pertinence initiale de 0,9 également, le nombre maximale de règles correspond au nombre maximal de règles générées avant l'élimination des premières règles, soit un peu moins de 20.
A spécificité égale et à score égale, par définition, une nouvelle règle a priorité sur les précédentes. Cela explique, avec la requête SQL suivante, que dans la représentation graphique de l'activation des règles toute nouvelle règle supplante les précédentes.
Dans l'essai ci-dessous, la dynamique s’éteint au bout d'environ 220 pas, mais la dynamique déraille bien avant, vers le 120ième pas. L'absence d'un évènement qui n'est plus généré entraine la production d'une anomalie qui annule le processus de création de règles. Vers la fin, les règles disparaissent mais, ce faisant, simplifient et autorisent la création de certaines règles sans que cela soit néanmoins suffisant.
SELECT DISTINCT log.time, rule_id, hue, type.luminance + 40 AS luminance, saturation FROM log NATURAL JOIN rule JOIN type ON type.type_id = rule.type_id ORDER BY log.time
Une représentation illustrant davantage les quatre phases d'un cycle de production s'obtient avec la requête SQL suivante :
SELECT time, rule_id, (time/500)%4 AS color FROM log
La raison de la courte durée de la dynamique s'explique par la courte durée de vie des règles créées. Les règles initiales possèdent une durée de vie équivalente mais elles sont synchrones entre elles, alors que les règles créées arrivent en décalé quatre par quatre. Ce faisant, la plage de 80 pas permettant d'assurer à 94,5% la production d'un ensemble de règles viable n'est plus garanti.
Une solution consiste à augmenter la pertinence des règles créées en passant de 0,9 à 0,999 leur donnant une durée de 105 pas au lieu de 80. Le graphique suivant montre le résultat de cet allongement, le maintien de la dynamique sur plus de 500 pas.
Une autre manière de percevoir la dynamique et ses passages de danger consiste à visualiser la pertinence (relevance) des règles sélectionnées avec la requête SQL suivante :
SELECT time, relevance, rule_id AS color FROM log