A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
Experimente online!
Define um predicado +/2que pega uma string (na forma de uma lista de códigos de caracteres) como seu primeiro argumento ( A) e define seu segundo argumento ( B) na ordem da rotação simétrica da ordem mais alta.
Explicação
Este programa usa o fato de que o conjunto de rotações simétricas em uma sequência é um grupo cíclico e, portanto, a ordem do conjunto de rotações simétricas é igual à ordem da rotação simétrica de ordem mais alta. Assim, o programa é capaz de calcular o resultado desejado, localizando o número total de rotações simétricas na sequência de entrada.
Código Explicação
A maior parte do trabalho pesado é feita por uma chamada ao findall/3predicado. O findall/3predicado encontra todos os diferentes valores possíveis para o primeiro argumento ( Xneste caso), de modo que a expressão fornecida como segundo argumento seja verdadeira ( (append(X,Y,A),append(Y,X,A)), mais sobre isso posteriormente). Finalmente, ele armazena cada um desses valores possíveis Xcomo uma lista no argumento final ( [_|Z]).
A expressão transmitida findall/3como a segunda versão, (append(X,Y,A),append(Y,X,A))usa o append/3predicado para especificar que Xconcatenado com alguns ainda não definidos Ydeve ser igual a A, a sequência de entrada e que o mesmo Yconcatenado Xtambém deve ser igual a A. Isso significa que Xdeve haver algum prefixo para Aque, se for removido da frente Ae adicionado à parte traseira, a sequência resultante seja a mesma que A. O conjunto de Xs com essa propriedade tem quase uma correspondência individual com as rotações simétricas de A. Sempre há exatamente um caso de contagem dupla causado pelo fato de que a cadeia vazia e Aos prefixos deAque correspondem à rotação 0 de A. Como a 0rotação de Aé sempre simétrica, o comprimento da lista resultante de Xs findall/3será um maior que o número de rotações simétricas ativadas A.
Para resolver o problema da contagem dupla, utilizo a correspondência de padrões no terceiro argumento do findall/3predicado. No Prolog, as listas são representadas como pares de cabeça (o primeiro elemento) e cauda (o resto). Assim, [_|Z]representa uma lista cuja cauda é igual é igual a Z. Isso significa que o comprimento de Zé um menor que o número de prefixos encontrados pelo findall/3predicado e, portanto, igual ao número de rotações simétricas de A. Finalmente, eu uso o length/2predicado para definir Bo comprimento de Z.