====== 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**//), [[doc:langage_nomo#la_structure_de_creation_de_regles|une structure usine]] (//**plant**//) est ajoutée.
==== 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.
==== 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 [[doc:creation_de_regles#la_copie_d_un_evenement|à 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 :
Au même moment, [[doc:creation_de_regles#la_derivation_d_un_evenement|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 :
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 [[doc:creation_de_regles#la_determination_du_repere_temporel_de_la_regle|l'origine et le repère temporel]] se porte sur la perception créée, soit :
=== 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 :
=== 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 :
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 :
{{ :tutorial:tutorial_4_map_1.png?300 |}}
Le chronogramme du programme réalisé devient alors :
{{ :tutorial:fr:tutorial_4_chronogram_1_fr.png?700 |}}
L'image de la mémoire événementielle au huitième coup d'horloge correspond au tableau suivant :
{{ :tutorial:tutorial_4_tab_0.png?700 |}}
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 :
==== 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 :
{{ :tutorial:tutorial_4_map_2.png?500 |}}
{{ :tutorial:fr:tutorial_4_chronogram_2_fr.png?720 |}}
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 :
{{ :tutorial:tutorial_4_tab_1.png?700 |}}
=== 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 :
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 :
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**//.
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 :
=== 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 :
=== 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 :
=== 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 :
{{ :tutorial:tutorial_4_tab_2.png?700 |}}
== 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 :
{{ :tutorial:tutorial_4_tab_3.png?700 |}}
== 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 :
{{ :tutorial:tutorial_4_tab_4.png?700 |}}
== 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 :
{{ :tutorial:tutorial_4_tab_5.png?700 |}}
== 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 :
{{ :tutorial:tutorial_4_tab_6.png?700 |}}
==== 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 :
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 :
...
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 :
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// :
Soit l'image de la mémoire évènementielle au douzième coup d'horloge :
{{ :tutorial:tutorial_4_tab_7.png?700 |}}
===== 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 :
La règle de détection d'un événement d'un type //**concept_a**// est alors :
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 :
{{ :tutorial:tutorial_4_map_2.png?500 |}}
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_01**//et 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 :
Suivi de leur affectation :
La règle //target_reference// dédiée au placement du repère temporel //**transform_in_temporal_reference**// identique aux exemples précédents :
=== La condition et la conclusion ===
La condition et la conclusion s'effectuent de la même manière dans tous les cas suivants :
Avec pour rappel, l'opérateur //**create_premise_1**// définit comme suit dans le modèle :
...
...
=== Analyse ===
L'état de la mémoire évènementielle au quatorzième coup d'horloge correspond au tableau suivant :
{{ :tutorial:tutorial_4_tab_8.png?700 |}}
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 :
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**// :
Le décalage induit par cet opérateur supprimera le délai de la conclusion, comme suit :
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"//.
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 :
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 :
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 :
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 :
Les règles initiales, sans les règles dédiées à la création de règles, correspondent aux règles suivantes :
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 :
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 :
Il reste alors à corriger la référence temporelle du concept créé et à placer le repère temporel de la règle :
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.
{{ :tutorial:tutorial_4_map_3.png?600 |}}
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 :
{{ :tutorial:tutorial_4_map_4.png?400 |}}
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 :
{{ :tutorial:tutorial_4_graph_1_bis.png?650 |}}
===== 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.
{{ :tutorial:tutorial_4_tab_9.png?700 |}}
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 :
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.
{{ :tutorial:tutorial_4_graph_5.png?450 |}}
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
{{ :tutorial:tutorial_4_graph_2.png?650 |}}
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
{{ :tutorial:tutorial_4_graph_3.png?650 |}}
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.
{{ :tutorial:tutorial_4_graph_4.png?650 |}}
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
{{ :tutorial:tutorial_4_graph_6.png?650 |}}