То, что я хотел сделать, это сгенерировать все комбинации элементов из данного списка. Например: Из [a, b, c], я могу:Как связать все комбинации пролога с clp (fd)?
[]
[a]
[b]
[c]
[a,a]
[a,b]
[a,c]
[b,a]
...
И так далее. Возможно, есть волшебный пролог с одним слоем, который делает это. Если так, я хотел бы это услышать.
Однако мой вопрос не в том, чтобы решить эту конкретную проблему и в большей части запроса, чтобы кто-то объяснил мне некоторые тонкости алгоритма поиска Prolog.
Так вот пока что я сделал первый решить вышеуказанную проблему:
members([], _).
members([X|Xs], List) :-
member(X,List),
members(Xs, List).
Это прекрасно работает, но возвращает все возможные результаты, а не в большом порядке:
[]
[a]
[a,a]
[a,a,a]
Хорошо, что нет проблема. Я просто хочу, чтобы все комбинации были до определенной длины. Поэтому я решил сначала получить те, которые имеют точно определенную длину:
membersWithLength(Members, List, Bound) :-
L = Bound,
length(Members, L), members(Members, List).
Это прекрасно работает, например. для длины 2:
[a,a]
[a,b]
[a,c]
...
И так далее. Теперь моя попытка использовать clpfd использовать описанную выше функцию, чтобы получить все списки до определенной длины пошло наперекосяк:
:- use_module(library(clpfd)).
membersLessThan(Members, List, Bound) :-
L in 0..Bound, % I also tried L #=< Bound
membersWithLength(Members, List, L).
Вид работ. Находит правильные результаты (списки с длиной меньше, чем Bound). Но после того, как он находит их, он непрерывно ищет больше результатов. Например. для длины 2:
[]
[a]
[b]
[c]
[a,a]
[a,b]
...
[c,c]
Hangs looking for more solutions.
Я думаю, что это сердце моего вопроса. Может кто-нибудь объяснить, почему (по следам) пролог продолжает проверять более крупные и большие списки как возможные решения, даже если они все обречены на провал? И может ли кто-нибудь сказать мне, есть ли способ помочь прологу избежать этого обреченного пути?
В конечном итоге я использовал следующий код для решения проблемы, но я был разочарован тем, что не мог понять, как использовать ограничения целочисленного clpfd, чтобы ограничить размер списков.
membersLessThan_(Members, List, Bound) :-
numlist(0,Bound,ZeroToBound),
member(L, ZeroToBound),
membersWithLength(Members, List, L).
Здесь все соответствующий код на SWISH: http://swish.swi-prolog.org/p/allcombos.pl
К сожалению, clpfd и условия не собираются вместе. – false
См. Http://stackoverflow.com/questions/32478193/using-a-constrained-variable-with-length-2/32501766 – jschimpf
Я думаю, что вы можете быть правым @false. Не могли бы вы указать мне некоторые ресурсы, которые описывают такие вещи, как: 1) почему они не стекаются хорошо, 2) в каких ситуациях они делают или нет, или 3) какие типичные стратегии преодоления могут быть, когда они не ? Или, если у вас будет хорошее понимание этих концепций, я был бы признателен, если бы вы могли объяснить это мне. –