(B(B(C B C)(B(C(B(B(C(B B C)C))B)C)))C)ou
(B(B(B(B W)B)C(B W B)(B W B))K)dire si ce combinateur est inversible dans le monoïde (CL0+ext,B,I); si oui quel est son inverse? Si non pourquoi? Pour répondre à cette question nous utiliserons les résultats théoriques du chapitre 2. Nous connaissons la forme des combinateurs inversibles, il doivent être éléments de P. On rappelle que P est défini récursivement par:
1'. P est dans P où P est un permutateur régulier.La nouvelle définition obtenue est évidemment équivalente à la précédente car I est un permutateur régulier particulier et que dans la condition 2 ci-dessus il suffit de remplacer P1 P2 P3 … Pn par I pour obtenir un permutateur régulier.Ceci va nous permettre d'éliminer I dans les abstractions et de donner les inverses en termes de B et C exclusivement. Si on veut donc s'en tenir aux critères d'inversibilité developpés dans le chapitre 2 il nous faut prendre la λ-expression en forme normale associée au combinateur si elle existe. Étant donné que nous disposons de la règle d'extensionalité nous pouvons toujours associer une λ-expression à un combinateur, mais celle-ci aura une forme normale si et seulement si le combinateur en a une. On va donc travailler sur cette λ-expression associée au combinateur pour laquelle il suffira de vérifier son appartenance à P. On devra donc dans un premier temps transformer le combinateur donné sous forme de λ-expression qui sera mise en forme normale de tête.On devra obtenir une expression du genre
K = λ(x0 x1)(x0) ne peut pas être codé sans ambiguité dans ce système. Cependant nous le coderons (0) mais un compteur de variables associé à chaque codage nous permettra de savoir si le compte de variables y est. Ainsi I et K seront tous deux codés (0) mais le compteur de variables indiquera zéro pour I et un pour K permettant ainsi de savoir qu'il ne sont pas équivalents. Reprenons donc la forme (4.2):
C = λ(x0 x1 x2)(x0 x2 x1) sera codé (0 2 1) B = λ(x0 x1 x2)(x0 (x1 x2)) sera codé (0 (1 2)) S = λ(x0 x1 x2)(x0 x2 (x1 x2)) sera codé (0 2 (1 2)) W = λ(x0 x1)(x0 x1 x1) sera codé (0 1 1)
(0 (P1 f(1))(P2 f(2))…(Pn f(n)))Après avoir bien entendu vérifié que cette liste commence par 0 (régularité du combinateur), il suffit apparemment d'étudier chaque sous liste (Pi f(i)), de récupérer f(i) pour controler la permutation des variables au premier niveau et vérifier de la même manière que Pi veut bien à son tour se mettre sous la forme (4.2). Malheureusement pour nous la situation n'est pas aussi simple car les combinateurs, même inversibles n'auront qu'assez rarement le bon goût de vouloir se mettre sous la forme (4.2). Il faudra donc les y forcer. La raison en est que chaque λ-expression peut être représentée par une infinité de combinateurs équivalents. On peut avoir ainsi des combinateurs qui dupliquent un nombre arbitraire de fois des termes pour les détruire ensuite; c'est le cas du second exemple donné au début de ce chapitre qui n'est rien d'autre que I (on peut même montrer qu'il est équivalent à I sans utiliser l'extensionalité). Quelques exemples illustreront parfaitement les difficultés rencontrées mieux qu'un long discours. Soient donc les cinq combinateurs suivants:
C1=B(C(C(B(B(B(B C)B))C)C)K)BMalgré leur apparence de diversité ces cinq combinateurs sont équivalents et inversibles, et ne représentent rien d'autres qu'une forme compliquée du fameux permutateur C.
C2=B(C(B(B(C(B C)C)B))C)B
C3=B(C(B C)(C B I))B
C4=(B(B(B C(C B K))(B W))B
C5=C(C(B(B(B(B(B(B W)B))B)(B C))B)(C B))(K I)
C1 devient (0 (K 2 C) 1)Comme annoncé ces cinq combinateurs sont équivalents à C écrit sous la forme (0 (I 2) 1).
C2 devient (0 (C(C 2)) 1)
C3 devient (0 (C B I 2) 1)
C4 devient (0 (K 2 1) 1)
C5 devient (0 (C B(K I 1) 2) 1)
P=(0 (P1 f(1)) (P2 f(2))… (Pn f(n)))où f−1 désigne l'inverse de la permutation f et Pi−1 l'inverse du combinateur Pi. Prenons l'exemple:
P−1=(0 (Pf−1(1)−1 f−1(1)) (Pf−1(2)−1 f−1(2))… (Pf−1(n)−1 f−1(n)))
B(B(C B(B C(B C)))(B(B C(C B C))))Cqui s'écrit en forme normale de tête:
(0 (C 3) (B C(B C) 1) 2)La permutation du premier niveau à récupérer et à controler comme étant bien une permutation est (0 3 1 2); puis on met C sous forme normale de tête, on obtient (0 2 1) et de même pour B C(B C) qui donne (0 2 3 1); ce sont des permutateurs réguliers le combinateur ci-dessus est donc décrété inversible. Sa forme normale complète en terme de λ-expression est:
(0 ((0 2 1) 3) ((0 2 3 1) 1) 2)et c'est elle qu'il nous faut inverser puis abstraire. D'abord on peut remarquer qu'il y a des parenthèses dont on pourrait se passer moyennant une petite convention; on peut en effet écrire:
(0 (0 2 1) 3 (0 2 3 1) 1 2)à condition de convenir que le nombre qui suit une sous liste est la variable associée au combinateur representé par la sous liste. Ceci à l'avantage de faire apparaitre chaque permutation comme étant la liste des atomes d'une liste et se repère très facilement avec cette convention d'écriture. En réalité pour des raisons de facilité de programmation dues au langage LISP utilisé nous écrivons ce combinateur comme suit:
(0 3 (0 2 1) 1 (0 2 3 1) 2)On a donc:
(0 f(1) P1 f(2) P2 f(3) P3)Ici P3 correspond à I qui est repéré par son absence. Il nous faut donc récupérer la liste suivante:
(0 3 (0 2 1) 1 (0 2 3 1) 2)
(0 f−1(1) Pf−1(1)−1 f−1(2) Pf−1(2)−1 f−1(3) Pf−1(3)−1)Or
(0 f(1) f(2) f(3)) = (0 3 1 2)donc
(0 f−1(1) f−1(2) f−1(3)) = (0 2 3 1)On vient donc de récupérer l'inverse de la permutation du premier niveau il nous faut maintenant calculer les Pf−1(i)−1. On a
Pf−1(1)−1=P2−1=(0 3 1 2)L'inverse correspond donc à la liste:
Pf−1(2)−1=P3−1=I
Pf−1(3)−1=P1−1=C
(0 2 (0 3 1 2) 3 1 (0 2 1))On met ensuite cette liste sous la forme correspondant à la λ-expression. On obtient:
(0 ((0 3 1 2) 2) 3 ((0 2 1) 1))et on l'abstrait en commençant par les permutateurs du fond de la liste ce qui donne:
(0 (B(B C)C 2) 3 (C 1))Puis on abstrait à nouveau le résultat obtenu et ceci jusqu'à ce qu'il n'y ait plus de zéro en début de liste. Résultat final:
C(C(B(B(B(B B C))B)(B C)(B(B C)C))C.Les pages suivantes présentent le programme correspondant écrit en VLISP sur le système MULTICS de l'Université de Rennes ainsi qu'une petite session montrant ses possibilités. Ce programme dans cette version est volontairement bavard. Il occupe 2348 doublets en mémoire.