A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Pruébalo en línea!
Define un predicado +/2que toma una cadena (en forma de una lista de códigos de caracteres) como su primer argumento ( A) y establece su segundo argumento ( B) en el orden de la rotación simétrica de mayor orden.
Explicación
Este programa utiliza el hecho de que el conjunto de rotaciones simétricas en una cadena es un grupo cíclico y, por lo tanto, el orden del conjunto de rotaciones simétricas es igual al orden de la rotación simétrica de mayor orden. Por lo tanto, el programa puede calcular el resultado deseado al encontrar el número total de rotaciones simétricas en la cadena de entrada.
Explicación del código
La mayor parte del trabajo pesado se realiza mediante una llamada al findall/3predicado. El findall/3predicado encuentra todos los diferentes valores posibles para el primer argumento ( Xen este caso) de modo que la expresión dada como el segundo argumento sea verdadera ( (append(X,Y,A),append(Y,X,A))más sobre eso más adelante). Finalmente, almacena cada uno de estos posibles valores de Xcomo una lista en el argumento final ( [_|Z]).
La expresión que se pasa findall/3como el segundo argumento, (append(X,Y,A),append(Y,X,A))usa el append/3predicado para especificar que Xconcatenado con algo aún indefinido Ydebe ser igual a A, la cadena de entrada, y que el mismo Yconcatenado Xtambién debe ser igual a A. Esto significa que Xdebe ser un prefijo de Atal manera que si se elimina del frente Ay se agrega a la parte posterior, la cadena resultante es la misma que A. El conjunto de Xs con esta propiedad casi tiene una correspondencia uno a uno con las rotaciones simétricas de A. Siempre hay exactamente un caso de doble conteo que se debe al hecho de que tanto la cadena vacía como Alos prefijos deAque corresponden a la rotación 0 de A. Dado que la 0rotación de Asiempre es simétrica, la longitud de la lista resultante de Xs findall/3será mayor que la cantidad de rotaciones simétricas en A.
Para resolver el problema del conteo doble, utilizo la coincidencia de patrones en el tercer argumento del findall/3predicado. En Prolog, las listas se representan como pares de su cabeza (el primer elemento) y su cola (el resto). Por lo tanto, [_|Z]representa una lista cuya cola es igual a Z. Esto significa que la longitud de Zes menor que el número de prefijos encontrados por el findall/3predicado y, por lo tanto, igual al número de rotaciones simétricas de A. Finalmente, uso el length/2predicado para establecer Bla longitud de Z.