A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Essayez-le en ligne!
Définit un prédicat +/2qui prend une chaîne (sous la forme d'une liste de codes de caractères) comme premier argument ( A) et définit son deuxième argument (B ) à l'ordre de la rotation symétrique d'ordre le plus élevé.
Explication
Ce programme utilise le fait que l'ensemble des rotations symétriques sur une chaîne est un groupe cyclique et donc l'ordre de l'ensemble des rotations symétriques est égal à l'ordre de la rotation symétrique d'ordre le plus élevé. Ainsi, le programme est capable de calculer le résultat souhaité en trouvant le nombre total de rotations symétriques sur la chaîne d'entrée.
Explication du code
La majorité du levage lourd se fait par un appel au findall/3prédicat. Le findall/3prédicat trouve toutes les différentes valeurs possibles pour le premier argument ( Xdans ce cas) de telle sorte que l'expression donnée comme deuxième argument soit vraie ( (append(X,Y,A),append(Y,X,A)), plus à ce sujet plus tard). Enfin, il stocke chacune de ces valeurs possibles Xsous forme de liste dans l'argument final ( [_|Z]).
L'expression passée en findall/3tant que deuxième arugment, (append(X,Y,A),append(Y,X,A))utilise le append/3prédicat pour spécifier celui Xconcaténé avec certains encore indéfinisY doit être égale à A, la chaîne d'entrée, et que la même Yconcaténation avec Xdoit également être égale à A. Cela signifie qu'il Xdoit y avoir un préfixe Atel que s'il est supprimé de l'avant Aet ajouté à l'arrière, la chaîne résultante est la même que A. L'ensemble de Xs avec cette propriété a presque une correspondance biunivoque avec les rotations symétriques de A. Il y a toujours exactement un cas de double comptage qui est dû au fait que la chaîne vide et Ales préfixes deA qui correspondent à la rotation 0 de A. Depuis la 0rotation deAest toujours symétrique, la longueur de la liste résultante de Xs findall/3sera supérieure de un au nombre de rotations symétriques surA .
Pour résoudre le problème du double comptage, j'utilise la correspondance de motifs sur le troisième argument du findall/3prédicat. Dans Prolog, les listes sont représentées par des paires de leur tête (le premier élément) et de leur queue (le reste). Ainsi , [_|Z]représente une liste dont la queue est égale est égale à Z. Cela signifie que la longueur de Zest inférieure de un au nombre de préfixes trouvés par lefindall/3 prédicat et donc égale au nombre de rotations symétriques de A. Enfin, j'utilise le length/2prédicat pour définir Bla longueur de Z.