Ошибка «Out of global stack» обычно означает, что ваша рекурсия застряла в бесконечном цикле и, таким образом, продолжает вызывать предикат до тех пор, пока стек не будет исчерпан. Цикл вызван тем, что он сначала выдаст результаты:
?- compose(L1,L2,[a,b,c]).
L1 = [a, b, c],
L2 = [] ;
L1 = [],
L2 = [a, b, c] ;
L1 = [a, c],
L2 = [b] ;
Но тогда он будет искать другие решения. Он делает это, основываясь на вашей программе, каждый раз объединяя первый элемент с [H1|T1]
, а второй с [H2|T2]
. Затем вы немедленно делаете рекурсивный вызов, поэтому Пролог не может проверить, действительно ли H1
и H2
являются первыми двумя элементами в третьем параметре.
Однако нам не нужны все эти append/3
звонки и т. д. в первую очередь. Мы можем выполнить простую унификацию параметров:
compose([],L2,L2).
compose(L1,[],L1).
compose([H1|T1],[H2|T2],[H1, H2|T3]) :-
compose(T1,T2,T3).
Для данного запроса это закончится после предложенного решения:
?- compose(L1,L2,[a,b,c]).
L1 = [],
L2 = [a, b, c] ;
L1 = [a, b, c],
L2 = [] ;
L1 = [a],
L2 = [b, c] ;
L1 = [a, c],
L2 = [b] ;
false.
Действительно, так как из-за рекурсии, в конце концов, третийПараметр будет пустым списком и, следовательно, не сможет объединиться со списком [H1, H2|T3]
.