В вашем определении flatten / 2 есть некоторые ошибки:
Ваше первое предложение не будет выполнено, потому что если A - список, он сначала создаст экземпляр R1 с R, а затем вы попытаетесь снова объединить его с flatten (B, R1).
сглаживаются (X, X).-> Этот пункт оставляет список «как есть» без выравнивания.
Проверьте эту другую реализацию:
flatten(List, Flattened):-
flatten(List, [], Flattened).
flatten([], Flattened, Flattened).
flatten([Item|Tail], L, Flattened):-
flatten(Item, L1, Flattened),
flatten(Tail, L, L1).
flatten(Item, Flattened, [Item|Flattened]):-
\+ is_list(Item).
Здесь мы используем два предиката: flatten / 2 и flatten / 3.«Работа» будет выполнена в flatten / 3, где второй аргумент будет содержать промежуточный плоский список.
Первое предложение является базовым случаем: когда мы достигаем пустого списка, мы выполняем, поэтому создаем экземпляр третьегоаргумент с промежуточным плоским списком.
Второй пункт касается рекурсии.Он выравнивает первый элемент в списке (будь то элемент или подсписок) и переходит к остальной части входного списка.
Последнее предложение является «базовым случаем» для элементов, не входящих в список,Он добавляет элемент в начало промежуточного уплощенного списка, но делает это только для элементов, которые не являются списками, как это было учтено во втором пункте.