Сначала мы можем решить связанную проблему: учитывая список "голов" 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]].
. С учетом того, что вышеприведенное генерирование перекрестного произведения из трех наборов должно быть простым, я оставляю это как упражнение.