【问题标题】:Prolog list manipulationProlog 列表操作
【发布时间】:2013-09-27 01:52:21
【问题描述】:

我有一个问题,需要有人纠正我:

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).

当我咨询时,无论我输入什么类型的书,我都会返回 false。如何解决?

【问题讨论】:

  • 尝试store(_, _, Books) 而不是store(_, [_], [Books])[Books] 只会匹配带有单个原子的列表,并用该单个原子实例化 Books。而[_] 也将只匹配具有单个原子而不是任何列表的列表。这两种情况都会导致与您的所有事实不匹配。
  • 每次答案匹配时返回true。例如,对于故事书,“真实”答案出现 2 次​​span>

标签: list prolog


【解决方案1】:

应用 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 而不是 member/2。它更快,并且作为副作用,避免在只有商店匹配但书籍不止一次出现的情况下回答 true。

为避免扫描整个数据库,可以使用连接:

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

最终剪辑可防止同一Book 出现多个无用答案。

【讨论】:

  • 你能解释一下这行先生吗:findall(, (store(,,Books), memberchk(Book, Books)), [, |])。特别是这部分---> [,_|]
  • 简单统一:[_,_|_] 匹配 any 列表长度>1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
相关资源
最近更新 更多