101 lines
2.6 KiB
Markdown
101 lines
2.6 KiB
Markdown
---
|
|
title: "Boucles"
|
|
weight: 30
|
|
---
|
|
|
|
Il est possible de construire des boucles dans le cas où des étoiles
|
|
peuvent être réutilisées.
|
|
|
|
# Boucles divergentes improductive
|
|
|
|
Il est recommandé d'utiliser l'option `-show-steps` pour cette partie.
|
|
|
|
```
|
|
-f(X) +f(X);
|
|
@+f(X);
|
|
```
|
|
|
|
Dans l'exemple ci-dessus, on se concentre sur `@+f(X);` pour se connecter
|
|
à `-f(X)` et ainsi produire `+f(X)` sur lequel on se focalise puis on
|
|
recommence en utilisant la première étoile, et ce indéfiniement.
|
|
|
|
La boucle existe car il existe une compatibilité dans la première étoile
|
|
entre son premier rayon `-f(X)` et son second rayon `+f(X)` permettant sa
|
|
duplication et sa réutilisation.
|
|
|
|
# Boucles divergentes productives
|
|
|
|
En remplaçant le second rayon de `-f(X) +f(X);` de sorte à le rendre strictement
|
|
plus grand (en nombre de symboles) que le premier, il est possible de rendre
|
|
la boucle productive : elle ajoute de plus en plus de symboles. Par exemple :
|
|
|
|
```
|
|
-f(X) +f(s(X));
|
|
@+f(X);
|
|
```
|
|
|
|
Remarque : si on avait fait l'inverse avec
|
|
|
|
```
|
|
-f(s(X)) +f(X);
|
|
@+f(X);
|
|
```
|
|
|
|
on serait resté avec une boucle improductive qui dit simplement que ce nous
|
|
donnons (le `X` de `@+f(X)` ici) doit être identifié à `s(X)` mais au final
|
|
on produit du `X` sans utiliser le symbole `s` qui disparaît.
|
|
|
|
# Boucles convergeantes
|
|
|
|
Afin d'avoir une boucle convergente, il faut proposer des ressources sur
|
|
lesquelles on se focalise et avoir une boucle qui les consomme.
|
|
|
|
## Décroissance
|
|
|
|
On peut par exemple proposer une pile de symboles `s` dépilée par une étoile
|
|
de boucle :
|
|
|
|
```
|
|
-f(0) end;
|
|
-f(s(X)) +f(X);
|
|
@+f(s(s(s(0))));
|
|
```
|
|
|
|
On a ajouté une étoile `-f(0) end` pour repérer le moment où la
|
|
boucle laisse `0` (on a retiré tous les `s`) pour ensuite produire `end` en
|
|
sortie.
|
|
|
|
## Boucle for
|
|
|
|
En utilisant ces mécanismes, on peut simuler la boucle `for` de la programmation
|
|
impérative en ajoutant des rayons à l'étoile de boucle.
|
|
|
|
Voici une constellation qui affiche trois fois `hello` avec la valeur de
|
|
compteur associée :
|
|
|
|
```
|
|
-f(0) end;
|
|
-f(s(X)) +f(X) message(hello X);
|
|
@+f(s(s(s(0))));
|
|
```
|
|
|
|
# Exemple : addition unaire
|
|
|
|
Un exemple typique de boucle est le programme de programmation logique qui
|
|
calcule la somme d'entiers unaires :
|
|
|
|
```
|
|
+add(0 Y Y);
|
|
-add(X Y Z) +add(s(X) Y s(Z));
|
|
|
|
@-add(s(s(0)) s(s(0)) R) R; 'query
|
|
```
|
|
|
|
Ici, on calcule la somme `2+2` et on récupère le résultat dans `R`.
|
|
|
|
# Cas général
|
|
|
|
Dans cette section, nous avons seulement considéré des étoiles de boucles
|
|
binaires mais il est tout à fait possible d'imaginer des choses plus compliquées
|
|
avec plusieurs étoiles qui forment plusieurs embranchements pour ensuite
|
|
réutiliser une étoile déjà utilisée. |