2013-09-27 6 views
1

У меня есть вопрос, и нужен кто-то исправить меня:Прологе список манипуляция

store(wyoming, [evan, sandra], [storybook, fiction, general]).
store(brooklyn, [haas, maria], [fiction, schoolbook, religion]).
store(oakland, [rich, walker, dina, vince], [storybook, schoolbook, fiction]).

если я консультируйтесь ?-locations(storybook). ответ должен вернуться так, потому что сборник рассказов доступны более чем в одном магазине. Я пишу свой предикат следующим образом:

locations(Book) :- store(_, [_], [Books]), member(Book, Books). 

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

+2

Попробуйте 'store (_, _, Books)' вместо 'store (_, [_], [Books])'. '[Books]' будет соответствовать только списку с одним атомом и создавать экземпляры 'Books' с этим единственным атомом. И '[_]' также будет соответствовать списку только с одним атомом, а не с любым списком. Оба они вызовут неправильную совпадение со всеми вашими фактами. – lurker

+0

возвращает true каждый раз, когда отвечает ответ. например, для сборников рассказов «истинный» ответ появляется 2 раза – Man

ответ

0

После применения предложения mbratch вам все равно необходимо проверить, когда Book доступен в более чем одном магазине. Самый простой способ, неэффективна, потому что если 'анализ' все БД:

locations(Book) :- 
    findall(Book, (store(_,_,Books), memberchk(Book, Books)), L), 
    length(L, N), N > 1. 

Мы можем сделать его менее многословным:

locations(Book) :- 
    findall(_, (store(_,_,Books), memberchk(Book, Books)), [_,_|_]). 

Примечание Я memberchk/2 вместо члена/2. Это быстрее и, как побочный эффект, позволяет избежать ответа на истину в случае, когда есть только совпадение магазина, но с книгой, представленной более одного раза.

Чтобы избежать сканирования всей базы данных, объединение будет делать:

locations(Book) :- 
    store(X,_,BooksX), memberchk(Book,BooksX), 
    store(Y,_,BooksY), Y \= X, memberchk(Book,BooksY), 
    !. 

Окончательный срез предотвращает несколько бесполезных ответов на тот же Book.

+0

вы можете объяснить эту строку сэр: findall (_, (store (_, _, Books), memberchk (книга, книги)), [_, _ | _]). особенно эта часть ---> [_, _ | _] – Man

+0

простая унификация: '[_, _ | _]' соответствует * любому * списку с длиной> 1 – CapelliC

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