@ Решение Петериса излишне сложное.Вы можете сделать это так:
equal_lengths([]).
equal_lengths([[]]).
equal_lengths([[_|_]]).
equal_lengths([X,Y|Rest]) :-
length(X, Len),
length(Y, Len),
equal_lengths([Y|Rest]).
Думайте индуктивно.Я утверждаю, что длина пустого списка и список из одного списка "равны" (нет / только один другой для сравнения).Затем я говорю, если длина первого элемента равна длине второго элемента, при условии, что длина второго элемента и остальных совпадают, мы хороши.
Примечание: мыявно не говорите, что длина X и Y одинакова с некоторым тестом на равенство.Мы позволяем Прологу справиться с этим для нас, просто объявив, что длина X и Y - это Len.Поэтому, если длина Y не объединяется с длиной X, предикат завершится ошибкой.
Поворот процесса
Итак, чтобы написать предикат для определенияесли ни один из списков не имеет одинаковую длину, мы должны заметить, что на этот раз нам придется отслеживать, какие длины были замечены до сих пор для проверки.Мы должны сравнить длину каждого списка со всеми предыдущими длинами списка, чтобы определить неравенство.Поэтому на этот раз наш начальный случай создаст начальный список длин и отложит обработку до другого предиката, например, так:
unequal_lengths(X) :- unequal_lengths(X, []).
Теперь мы снова начнем с аналогичных базовых случаев:
unequal_lengths([], _).
unequal_lengths([[]], _).
unequal_lengths([[_|_]], _).
Вещистановиться интереснее, когда у нас есть фактический список:
unequal_lengths([X|Rest], Lengths) :-
length(X, Len),
\+ member(Len, Lengths),
unequal_lengths(Rest, [Len|Lengths]).
Итак, мы вычисляем длину этого списка, затем утверждаем, что это не та длина, которую мы видели раньше с помощью удобного предиката члена, а затем пропускаем этодлина вместе с остальной частью до остальной части списка.
Приложение: неравное с / о
Вдохновленные другими ответами, вы можете реализовать unsqual_lengths в более высоком-порядок моды так:
unequal_lengths(Lists) :-
findall(Len, (member(X, Lists), length(X, Len)), Lengths),
forall(select(Len, Lengths, Remaining), \+ member(Len, Remaining)).
Если подумать, это очень близко соответствует формальному логическому выражению проблемы: для каждой длины списка не существует элемента оставшихся длин спискасоответствующий этому.