序言否定
我正在尝试解决 Prolog 中使用否定的简单查询,但我无法破解它。查询是“查找从未售出的类别”。
知识库如下:
category(stationery, 30, 200, 10, 2).
category(books, 10, 30, 3, 2).
category(consumables, 50, 300, 15, 3).
item(pen, stationery, 10, 150).
item(colgate_small, consumables, 20, 65).
item(colgate_medium, consumables, 45, 70).
item(colgate_big, consumables, 70, 34).
item(juice_small, consumables, 45, 23).
item(juice_medium, consumables, 60, 23).
item(juice_big, consumables, 80, 12).
item(book, stationery, 5, 65).
item(pencil, stationery, 7, 56).
item(newspaper, books, 50, 400).
sale(tom, 1/1/07, pen, 3).
sale(peter, 1/1/07, book, 85).
sale(peter, 1/1/07, juice_small,1).
sale(alice, 7/1/07, pen, 10).
sale(alice, 7/1/07, book, 5).
sale(patrick, 12/1/07, pen, 7).
I am trying to solve a simple query in Prolog that uses negation but I can't crack it. The query is "Find the categories that have never been sold".
The knowledge base is as follows:
category(stationery, 30, 200, 10, 2).
category(books, 10, 30, 3, 2).
category(consumables, 50, 300, 15, 3).
item(pen, stationery, 10, 150).
item(colgate_small, consumables, 20, 65).
item(colgate_medium, consumables, 45, 70).
item(colgate_big, consumables, 70, 34).
item(juice_small, consumables, 45, 23).
item(juice_medium, consumables, 60, 23).
item(juice_big, consumables, 80, 12).
item(book, stationery, 5, 65).
item(pencil, stationery, 7, 56).
item(newspaper, books, 50, 400).
sale(tom, 1/1/07, pen, 3).
sale(peter, 1/1/07, book, 85).
sale(peter, 1/1/07, juice_small,1).
sale(alice, 7/1/07, pen, 10).
sale(alice, 7/1/07, book, 5).
sale(patrick, 12/1/07, pen, 7).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
Sam Segers 的答案是正确的,尽管它会给您未售出的类别列表。
如果您不需要聚合,而是需要一个谓词,该谓词将回溯所有没有售出任何商品的类别,您可以编写如下内容:
此谓词在回溯时,将生成所有没有售出商品的类别。
Sam Segers answer is correct, though it will give you the list of categories not sold.
If you don't want an aggregation but rather a predicate which will backtrack over all the categories which do not have any items sold you would write something like this:
This predicate, upon backtracking, will yield all the categories for which no items where sold.
可能不是最有效的方法。
但我认为它应该有效。
Might not be the most efficient way.
But I think it should work.
您是否知道 Prolog 的 negation-as-failure (控制)谓词,\+/1?当且仅当目标无法被证明时,它才是
true
。使用谓词,任务可以简化为查找已售出的类别,即
,
如果您想要所有这些类别的列表,只需使用 findall 谓词即可。
Are you aware of Prolog's negation-as-failure (control) predicate, \+/1? It is
true
iff the goal cannot be proven.Using the predicate, the task reduces to finding categories that have been sold, i.e.
and
If you want a list of all those categories, simply use the findall predicate.
正如 Sam Segers 提到的,您可以在表达式周围放置 not() 。
您还可以使用 \+ 运算符在逻辑上否定谓词:
As Sam Segers mentioned you can put a not() around an expression.
You can also use the \+ operator to logically negate a predicate:
用法:
Usage: