Поскольку положение значений в подсписках фиксировано, и все подсписки заполнены:
harmony(As,Bs) :- maplist(dif,As,Bs).
harmonies(L,R) :-
forall((select(A,L,S),member(B,S)), harmony(A,B))
-> R=L
; select(_,L,T), harmonies(T,R)
.
creasing_harmonies(L,R) :-
setof(D-T,(harmonies(L,T),length(T,D)),R).
Не уверен, какой может быть «лучшая гармония». Предполагая, что это длиннее:
?- creasing_harmonies([[spanish, white, 5], [italian, red,4], [canadian, blue,2],[canadian,red,2],[spanish, blue,4]],L),last(L,B).
L = [1-[[canadian, blue, 2]], 1-[[canadian, red, 2]], 1-[[italian, red, 4]], 1-[[spanish, blue, 4]], 1-[[spanish, white|...]], 2-[[canadian|...], [...|...]], 2-[[...|...]|...], 2-[...|...], ... - ...|...],
B = 3-[[spanish, white, 5], [italian, red, 4], [canadian, blue, 2]].
Если у вашего Пролога нет dif / 2 или maplist / 3, аппроксимация может быть
harmony([],[]).
harmony([E|As],[E|Bs]) :- !, fail.
harmony([_|As],[_|Bs]) :- harmony(As,Bs).
редактировать
Пока что это очень неэффективно. Чтобы получить решение, необходимо уменьшить пространство поиска:
harmonies(L,R) :-
length(L,N),N>4,
( forall((select(A,L,S),member(B,S)), harmony(A,B))
-> R=L
; select(_,L,T), harmonies(T,R)
).
Но давайте посмотрим, сколько «решений» у нас есть сейчас
?- test_data(L),aggregate(count,harmonies(L,R),C).
L = [[table, green, alex, coffee, prince], [keyboard, green, alex, coffee, bookA], [keyboard, yellow, alex, water, bookA], [cup, red, alex, water, bookB], [computer, white, john, beer|...], [cup, red, birds|...], [keyboard, green|...], [keyboard|...], [...|...]|...],
R = [[table, green, alex, coffee, prince], [computer, white, john, beer, bookD], [cup, red, birds, milk, bookC], [keyboard, yellow, sabrina, water, bookA], [dane, blue, sasha, tea|...]],
C = 5040.
5040 дубликатов! Лучше остановиться на первом решении на фиксированной длине.
harmonies(L,N,R) :-
length(L,M),M>=N,
( forall((select(A,L,S),member(B,S)), harmony(A,B))
-> R=L
; select(_,L,T), harmonies(T,R)
).
?- test_data(L),harmonies(L,5,R).
L = [[table, green, alex, coffee, prince], [keyboard, green, alex, coffee, bookA], [keyboard, yellow, alex, water, bookA], [cup, red, alex, water, bookB], [computer, white, john, beer|...], [cup, red, birds|...], [keyboard, green|...], [keyboard|...], [...|...]|...],
R = [[table, green, alex, coffee, prince], [computer, white, john, beer, bookD], [cup, red, birds, milk, bookC], [keyboard, yellow, sabrina, water, bookA], [dane, blue, sasha, tea|...]] .