2014-11-08 3 views
2

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

suitables(L) :- setof(X, isSuitable(X), L). 

Каждый элемент сверху имеет счет через функтор, и мне нужно все подмножества, которые имеют балл> 10. Я знаю, как получить сумму оценки:

scoreSum([], 0). 
scoreSum([H,T], Tot) :- getScore(H,F),scoreSum(T, Rest), Tot is F+Rest. 

и условие может быть выражено следующим образом:

cond(L) :- scoreSum(L, R), R > 10. 

Как получить все подмножества, соответствующие данному условию? Я могу получить подмножества на основе ответа here, но как мне перебрать этот результат, чтобы получить только подмножества, соответствующие условию?

ответ

0

Я думаю, что нашел решение, в котором я нуждался, хотя я не уверен, что он эффективен или рекомендуется. При условии, что следующие функторы:

isSuitable(X) :- ... 

scoreSum([], 0). 
scoreSum([H,T], Tot) :- getScore(H,F),scoreSum(T, Rest), Tot is F+Rest. 

и условие:

cond(L) :- scoreSum(L, R), R > 10. 

я могу получить только наборы, которые удовлетворяют заданному условию:

suitables(L) :- setof(X, isSuitable(X), S), setof(R, (powerset(S, R), cond(R)),L). 

Где Powerset дает мне все подмножества данный комплект:

powerset([], []). 
powerset([_|T], P) :- powerset(T,P). 
powerset([H|T], [H|P]) :- powerset(T,P). 

Итак, вместо получения всех комбинаций, я основывался на this question, чтобы получить все наборы списка.

+0

Вызов этого отношения 'powerset/2' является немного неправильным. Powerset будет: 'powerset (M, P): - bagof (S, seq_subseq (M, S), P) .' – false

+0

Да, вы правы. Я изменю код. Спасибо за вашу помощь. – nowxue

2

Предоставленные scoreSum/2 начинается с scoreSum([H|T], Tot) :- ...

seq_subseq([], []). 
seq_subseq([_|Es], Fs) :- 
    seq_subseq(Es, Fs). 
seq_subseq([E|Es], [E|Fs]) :- 
    seq_subseq(Es, Fs). 

possiblesubset(S) :- 
    suitables(L), 
    seq_subseq(L, S), 
    cond(S). 

?- setof(S, possiblesubset(S), Subs). 

?- setof(S, (suitables(L), seq_subseq(L,S), cond(S)), Subs). % No L^ needed ; there is only one L. 

Однако, это довольно необычно для представления таких наборов в явном виде, просто потому, что Пролог может генерировать их так эффективно.

+1

Привет @false, спасибо за ответ. Я очень новичок в прологе, не могли бы вы рассказать о том, когда вы говорите: «Это довольно необычно, чтобы представлять такие наборы явно, просто потому, что Prolog может генерировать их так эффективно». Как я могу заставить пролог генерировать их? это мое предложенное решение? – nowxue

+1

Выше плюс ваше определение - правильное решение. Но редко бывает, что такие множества генерируются явно. То есть, список в 'Subs' может быть очень большим. С другой стороны, 'possiblesubset (S)' легко вызвать напрямую ** без ** генерации всего набора сразу. – false

Смежные вопросы