5

想象一下,我有以下知识库,它为每个人提供了他的名字和年龄。

person(mary, 39).
person(john, 24).
person(sandy, 17).

现在,我想检索所有 20 岁以上的人。此外,我只想收集他们的名字而不是他们的年龄。在这里,我想检索maryjohn

通常如何在 Prolog 中,更具体地说在 SWI-Prolog 中执行此操作?

如果我们使用非匿名变量,例如:

?- person(X, Y), Y > 20.

Prolog 会给我XY我不想要的值Y

我不能使用匿名变量_,因为 Prolog 不能链接它的两个实例。以下给出了错误:

?- person(X, _), _ > 20.

那么,如何做到这一点呢?

4

3 回答 3

6

这个答案直接跟进@danielp之前的答案

使用,您可以拥有以下任一:

  • 显示所有变量的答案替换(默认

  • 不显示变量的答案替换,例如_A

有关详细信息,请阅读您正在使用的 Prolog 处理器的手册!

对于SWI环境控制(Prolog 标志)current_prolog_flag/2. set_prolog_flag/2.

stefan@Lenovo ~ $ swipl
欢迎使用 SWI-Prolog(多线程,64 位,版本 7.3.15)
...

?- current_prolog_flag ( toplevel_print_anon , Flag)。% 获取默认
标志 ​​= true。

?- _A = 1。
_A = 1。

?- _A = 1,X = _A。
_A = X,X = 1。

?- set_prolog_flag (toplevel_print_anon, false)。% 切换标志
真的。

?- current_prolog_flag(toplevel_print_anon, Flag)。
标志 = 假。

?- _A = 1. %小心!
真的。

?- _A = 1,X = _A。
X = 1。

?- set_prolog_flag(toplevel_print_anon, true)。% 恢复标志
真的。

?- current_prolog_flag(toplevel_print_anon, Flag)。
标志 = 真。

?- _A = 1。
_A = 1。

?- _A = 1,X = _A。
_A = X,X = 1。
于 2016-01-21T07:07:25.457 回答
5

你为什么不定义一个谓词

ofintrest(X):- person(X,Y),Y>20.

一个查询

ofintrest(X).

如果您不想定义谓词,也可以使用双重否定

person(X,_) ,\+(\+ (person(X,Y), Y>20))
于 2016-01-20T06:05:24.757 回答
2

您可以定义一个谓词,该谓词已在CAFEBABE 的答案中发布。或者,您也可以给出一个以变量开头的名称,_其值不应出现在答案中(正如您已经指出的,出现的_总是不同的变量):

person(X,_Age), _Age > 20.

更新:这是特定于 Prolog 实现的。它适用于 SICStus,但默认情况下不适用于 SWI(请参阅重复的答案)。

于 2016-01-20T07:00:50.567 回答