Вы могли бы описать это отношение, переключив первые два аргумента в рекурсивном вызове, как предложено @WillNess в комментариях. А поскольку два списка могут различаться по длине, было бы полезно иметь предикат, который описывает списки в целом, чтобы избежать совпадения произвольных терминов в нерекурсивном правиле. Также было бы неплохо иметь несколько более описательное имя, которое отражает реляционную природу предиката. Учитывая все это, предикат может выглядеть примерно так:
islist([]).
islist([_|T]) :-
islist(T).
list_list_interlocked([],L,L) :-
islist(L).
list_list_interlocked([X|Xs],Ys,[X|Zs]) :-
list_list_interlocked(Ys,Xs,Zs).
Ваш пример запроса работает как ожидалось:
?- list_list_interlocked([1,2,3,4,5,6],[a,b,c],Zs).
Zs = [1, a, 2, b, 3, c, 4, 5, 6].
Предикат также работает, если второй список длиннее:
?- list_list_interlocked([1,2,3],[a,b,c,d,e,f],Zs).
Zs = [1, a, 2, b, 3, c, d, e, f].
И это работает только со списками:
?- list_list_interlocked(definitelynolist,[],Zs).
false.
?- list_list_interlocked([],definitelynolist,Zs).
false.
Последняя причина, по которой вам нужно islist/1
. Если вы определите нерекурсивное правило следующим образом: list_list_interlocked([],L,L).
, то Prolog может объединить произвольные термины с L
, и запрос выдаст неверный результат:
?- list_list_interlocked([],definitelynolist,Zs).
Zs = definitelynolist.
Предикат также можно использовать в другом направлении, например, Какие списки дают [1,a,2,b,3,c]
при блокировке? :
?- list_list_interlocked(X,Y,[1,a,2,b,3,c]).
X = [],
Y = [1, a, 2, b, 3, c] ;
X = [1, a, 2, b, 3, c],
Y = [] ;
X = [1],
Y = [a, 2, b, 3, c] ;
X = [1, 2, b, 3, c],
Y = [a] ;
X = [1, 2],
Y = [a, b, 3, c] ;
X = [1, 2, 3, c],
Y = [a, b] ;
X = [1, 2, 3],
Y = [a, b, c] ;
false.