На самом деле у меня есть три ответа для вас. Вы, вероятно, хотите третий. Но все равно пройдитесь по остальным.
1 Другая проблема
Я не уверен, что вы хотите описать отношение, которое вы описываете. Вы
также изучать OCaml и Python одновременно и на этих языках
что-то другое. Это означает что-то вроде:
zip([], [], []).
zip([], [_|_], []).
zip([_|_], [], []).
zip([X|Xs], [Y|Ys], [X-Y|XYs]) :-
zip(Xs, Ys, XYs).
?- zip([1,2],[3,4],XYs).
XYs = [1-3,2-4].
Обратите внимание на другое соглашение в Прологе. В то время как OCaml, Python, но также и Haskell используют (X, Y) для обозначения кортежа, в Prolog принято использовать (X-Y). Знак минус здесь не означает вычитание. Это просто не истолкованный термин.
Обычный способ реализовать это в Прологе - использовать maplist
. maplist
требует, чтобы все списки были одинаковой длины.
2 Чередование
(Правка) Другая интерпретация заключается в следующем. Имя как interlace/3
или shuffle/3
было бы идеально здесь. Недавно @salva показала нам очень красивое решение
этот. Не забудьте +1 это! Позвольте мне показать только несколько классных способов, как вы
можете использовать это:
?- shuffle([1,2],[3,4],Zs).
Zs = [1,3,2,4].
Это ты уже знаешь. Но зачем нам давать оба списка [1,2]
и [3,4]
Прологу? Это не простой язык программирования, который
заставляет тебя все рассказывать. Если вам лень вводить сложный список или другой термин, просто поместите переменную и посмотрите, как Пролог это выяснит. Итак, давайте заменим второй список
переменная.
?- shuffle([1,2],Ys,Zs).
Ys = [],
Zs = [1,2] ;
Ys = [_G607],
Zs = [1,_G607,2] ;
Ys = [_G607,_G616|_G617],
Zs = [1,_G607,2,_G616|_G617].
Таким образом, мы спрашиваем: как Ys
и Zs
должны выглядеть так, чтобы shuffle / 3 был истинным? На самом деле, есть 3 ответа для Ys
:
[]
- пустой список. Zs
- это тогда [1,2]
. Так что это одно решение.
[_G607]
- список с ровно одним элементом. Zs
это [1,_G607,2]
. _G607
является свободной переменной. У него может быть более приятное имя, но дело в том, что эта переменная встречается и в пределах Ys
и в Zs
. Этот ответ говорит: Все термины, которые входят в эту переменную, являются решениями. Таким образом, мы имеем здесь бесконечно много решений, выраженных в одном ответе.
[_G607,_G616|_G617]
означает список, содержащий не менее двух элементов.
Вот еще более интересный запрос:
?- shuffle(Xs,Xs,Zs).
Xs = Zs, Zs = [] ;
Xs = [_G592],
Zs = [_G592,_G592] ;
Xs = [_G592,_G601],
Zs = [_G592,_G592,_G601,_G601] ;
Xs = [_G592,_G601,_G610],
Zs = [_G592,_G592,_G601,_G601,_G610,_G610]
...
Посмотрите, как теперь есть дубликаты одной и той же переменной в Zs
!
3 переплетение
Может быть, это то, что вы на самом деле хотите:
intertwine([], [], []).
intertwine([E|Es], Fs, [E|Gs]) :-
intertwine(Es, Fs, Gs).
intertwine(Es, [F|Fs], [F|Gs]) :-
intertwine(Es, Fs, Gs).
В следующем запросе мы спрашиваем о списках, которые можно переплетать, чтобы получить список из трех элементов в результате!
?- length(Zs,3), intertwine(Xs,Ys,Zs).
Zs = Xs, Xs = [_G648,_G651,_G654],
Ys = [] ;
Zs = [_G648,_G651,_G654],
Xs = [_G648,_G651],
Ys = [_G654] ;
Zs = [_G648,_G651,_G654],
Xs = [_G648,_G654],
Ys = [_G651] ;
Zs = [_G648,_G651,_G654],
Xs = [_G648],
Ys = [_G651,_G654] ;
Zs = [_G648,_G651,_G654],
Xs = [_G651,_G654],
Ys = [_G648] ;
Zs = [_G648,_G651,_G654],
Xs = [_G651],
Ys = [_G648,_G654] ;
Zs = [_G648,_G651,_G654],
Xs = [_G654],
Ys = [_G648,_G651] ;
Zs = [_G648,_G651,_G654],
Xs = [],
Ys = [_G648,_G651,_G654].