Пролог создания списков - PullRequest
       6

Пролог создания списков

0 голосов
/ 15 октября 2018

Я пытаюсь написать программу на Прологе, которая будет принимать три списка (каждый из которых имеет одинаковую длину) и возвращает список списков.

Список списков, которые я возвращаю, представляет собой тройку, которая содержит элементы из трех передаваемых списков. Первый элемент тройки взят из первого переданного списка, второй элемент тройкииз второго списка, а третий элемент тройки из третьего переданного списка.

То, что я хочу получить, это список троек, которые функция возвращает, возвращая каждыйвозможная комбинация , которую можно составить из трех передаваемых списков.

На данный момент у меня есть некоторый код, который берет первые элементы из трех списков и делает из них тройку, а затем беретвторой элемент всех списков и делает из них тройку и так далее.Здесь это ниже.

   listCombos( [], [], [], []).
   listCombos( [A|AREST], [B|BREST], [C|CREST], [[A,B,C]|SOLUTION]) :-
       listCombos( AREST, BREST, CREST, SOLUTION).

Моя стратегия получения каждого комбо - взять первый элемент первого списка и первый элемент во втором списке, а затем пройти через все элементы в третьем списке.Как только я это сделаю, я перейду к первому элементу в первом списке и второму элементу во втором списке и сопоставлю их с каждым элементом в третьем списке.Затем, после того как я прошел второй список, переходите к первому списку.Дайте мне знать, если понадобятся дополнительные разъяснения.

Я новичок в Прологе, поэтому не понимаю, как превратить то, что я планирую сделать, в код.Я попробовал несколько вещей, но не увенчался успехом и получил несколько кодов ошибок, которые я не понимаю, поэтому трудно сказать, иду ли я в правильном направлении (я могу опубликовать некоторые из моих попыток, если это необходимо).Если у кого-то есть представление о том, в каком направлении мне следует идти, или какое-то объяснение того, что мне нужно сделать, это будет оценено.

Большое спасибо.

Ответы [ 4 ]

0 голосов
/ 03 ноября 2018

Подход Даниэля Лайонса хорош тем, что позволяет нам легко контролировать порядок комбинаций в перекрестном произведении списка списков, сохраняя при этом порядокэлементы в комбинациях одинаковы, конечно:

cross( [], [[]] ).
cross( [XS | T], R ):- 
    cross(   T,                     TC),
    findall( [X | Y], (                      %       or:
                         member( Y, TC),     %  member( X, XS)  
                         member( X, XS)      %  member( Y, TC),
                      ), 
                 R).

Обладает хорошей модульностью и разделением интересов: порядок представления не зависит от порядка генерации и порядка выбора.

0 голосов
/ 15 октября 2018

Сначала мы можем решить связанную проблему: учитывая список "голов" Hs и список "хвостов" Ts, составить все списки для всех голов H в Hs и всех хвостов T в Ts в списке.Мы можем сделать это с помощью предиката:

merge_all([], _, []).
merge_all([H|Hs], Ts, All) :-
    merge_single(Ts, H, All, D),
    merge_all(Hs, Ts, D).

merge_single([], _, D, D).
merge_single([T|Ts], H, [[H|T]|Rest], D) :-
    merge_single(Ts, H, Rest, D).

Например:

?- merge_all([a, b], [[1, 4], [2, 5]], R).
R = [[a, 1, 4], [a, 2, 5], [b, 1, 4], [b, 2, 5]].

Теперь мы можем использовать это, например, чтобы сделать все кросс-произведения с Cs и «пустое множество», например, если Cs = [a, b, c], то:

?- merge_all([a, b, c], [[]], RC).
RC = [[a], [b], [c]].

Учитывая, что у нас есть этот результат, мы можем сделать перекрестное произведение Bs с этим результатом.Например, если Bs = [1, 4], тогда мы получим:

?- merge_all([a, b, c], [[]], RC), merge_all([1, 4], RC, RB).
RC = [[a], [b], [c]],
RB = [[1, a], [1, b], [1, c], [4, a], [4, b], [4, c]].

. С учетом того, что вышеприведенное генерирование перекрестного произведения из трех наборов должно быть простым, я оставляю это как упражнение.

0 голосов
/ 19 октября 2018

Желательно обобщить искомую конструкцию, приняв список списков для объединения, следуя схеме из этого ответа :

combine(Ls,Rs) :- maplist(member,Rs,Ls).
listCombos(A,B,C, SOLUTION) :- findall(R,combine([A,B,C],R),SOLUTION).
0 голосов
/ 15 октября 2018

Зная маленький Пролог, самое очевидное решение - что-то вроде этого:

listCombos(Xs, Ys, Zs, Result) :-
    findall([X,Y,Z], 
            (member(X, Xs), member(Y, Ys), member(Z, Zs)),
            Result).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...