Собственно, у меня есть три ответа. Вы, наверное, захотите третьего. Но все равно пройдите через другие.
1 Другая проблема
Я не уверен, что вам нужны отношения, которые вы описываете. Вы также одновременно изучаете OCaml и Python, и на этих языках zip означает что-то еще. Это означает что-то вроде:
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). Знак минус здесь не означает вычитание. Это просто непонятный термин.
Обычный способ реализовать это в Prolog - использовать maplist
. maplist
требует, чтобы все списки были одинаковой длины.
2 чересстрочная развертка
(Edit) Другая интерпретация следующая. Имя вроде interlace/3
или shuffle/3
здесь было бы идеально. Недавно @salva показал нам очень красивое решение этой проблемы. Не забудьте поставить +1! Позвольте мне показать только несколько интересных способов его использования:
?- shuffle([1,2],[3,4],Zs).
Zs = [1,3,2,4].
Вы это уже знаете. Но зачем нам передавать оба списка [1,2]
и [3,4]
в Prolog? Это не простой язык программирования, который заставляет вас все рассказывать. Если вам лень вводить сложный список или другой термин, просто введите переменную и посмотрите, как Prolog это вычислит. Итак, заменим второй список переменной.
?- 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
должны выглядеть так, чтобы случайное / 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].
person
false
schedule
30.11.2011