Ответ в теме: Палиндром и почти палиндром – проверка на Prolog

#1907

Если использовать встроенные функции нельзя – скопируйте себе предикат reverse из статьи про обработку списков.

%% почти палиндром, с разрешенным количеством
%% отличающихся символов
% оба списка одновременно кончились - палиндром
palindrome([], [], _):-!.
% превышено разрешенное количество различий - не палиндром
palindrome(_, _, N):- N < 0, !, fail.
    % первые символы совпали
palindrome([H|T1], [H|T2], N):-
    % не изменяя N обработаем хвосты
    !, palindrome(T1, T2, N).
    % первые символы отличаются
palindrome([_|T1], [_|T2], N):-
    % уменьшим N, рекурсивно обработаем хвосты списков
    NN is N - 1, palindrome(T1, T2, NN).
 
%% проверка, является ли символ пробельным
is_space(C):- char_type(C, space).
 
% палиндром
pal_0(S):-
    % удаляем пробельные символы из строки
    exclude(is_space, S, SWS),
    % переворачиваем строку
    reverse(SWS, SWS).
% почти палиндром
pal_1(S):-
    % удаляем пробельные символы из строки
    exclude(is_space, S, SWS),
    % переворачиваем строку
    reverse(SWS, RSWS),
    % сравниваем списки с одним разрешенным различием
    palindrome(SWS, RSWS, 2).