序言。在查询中,如何在结果中不想要的变量上设置条件?
Prolog. In a query, how to put a condition on a variable that I do not want in the results?
假设我有以下知识库,它给出了每个人的名字和年龄。
person(mary, 39).
person(john, 24).
person(sandy, 17).
现在,我想检索所有 20 岁以上的人。此外,我只想收集他们的名字而不是他们的年龄。在这里,我想检索 mary
和 john
.
一般如何在 Prolog 中以及更具体地在 SWI-Prolog 中执行此操作?
如果我们使用非匿名变量,例如:
?- person(X, Y), Y > 20.
Prolog 会给我 X
和 Y
的值,我不想要 Y
.
我不能使用匿名变量 _
因为 Prolog 不能 link 它的两个实例化。下面报错:
?- person(X, _), _ > 20.
那么,如何做到这一点?
为什么不定义谓词
ofintrest(X):- person(X,Y),Y>20.
一个查询
ofintrest(X).
如果您不想定义谓词,您也可以使用双重否定
person(X,_) ,\+(\+ (person(X,Y), Y>20))
您可以定义一个谓词,因为已在 中发布。
或者,您也可以为其值不应出现在答案中的变量提供以 _
开头的名称(正如您已经指出的那样,_
的出现始终是不同的变量):
person(X,_Age), _Age > 20.
Update:这是特定于 Prolog 实现的。它适用于 SICStus,但默认情况下不适用于 SWI(参见 )。
这个答案直接跟进@danielp 。
使用 prolog-toplevel of swi-prolog 你可以选择其中之一:
显示所有变量的答案替换(默认值)
不显示 _A
等变量的答案替换
有关详细信息,请阅读您正在使用的 Prolog 处理器的手册!
为 SWI: Environment Control (Prolog flags)。
current_prolog_flag/2
。
set_prolog_flag/2
.
stefan@Lenovo ~ $ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.15)
...
?- current_prolog_flag(toplevel_print_anon, Flag). % get default
Flag = true.
?- _A = 1.
_A = 1.
?- _A = 1, X = _A.
_A = X, X = 1.
?- set_prolog_flag(toplevel_print_anon, false). % toggle flag
true.
?- current_prolog_flag(toplevel_print_anon, Flag).
Flag = false.
?- _A = 1. % watch out!
true.
?- _A = 1, X = _A.
X = 1.
?- set_prolog_flag(toplevel_print_anon, true). % restore flag
true.
?- current_prolog_flag(toplevel_print_anon, Flag).
Flag = true.
?- _A = 1.
_A = 1.
?- _A = 1, X = _A.
_A = X, X = 1.
假设我有以下知识库,它给出了每个人的名字和年龄。
person(mary, 39).
person(john, 24).
person(sandy, 17).
现在,我想检索所有 20 岁以上的人。此外,我只想收集他们的名字而不是他们的年龄。在这里,我想检索 mary
和 john
.
一般如何在 Prolog 中以及更具体地在 SWI-Prolog 中执行此操作?
如果我们使用非匿名变量,例如:
?- person(X, Y), Y > 20.
Prolog 会给我 X
和 Y
的值,我不想要 Y
.
我不能使用匿名变量 _
因为 Prolog 不能 link 它的两个实例化。下面报错:
?- person(X, _), _ > 20.
那么,如何做到这一点?
为什么不定义谓词
ofintrest(X):- person(X,Y),Y>20.
一个查询
ofintrest(X).
如果您不想定义谓词,您也可以使用双重否定
person(X,_) ,\+(\+ (person(X,Y), Y>20))
您可以定义一个谓词,因为已在 _
开头的名称(正如您已经指出的那样,_
的出现始终是不同的变量):
person(X,_Age), _Age > 20.
Update:这是特定于 Prolog 实现的。它适用于 SICStus,但默认情况下不适用于 SWI(参见
这个答案直接跟进@danielp
使用 prolog-toplevel of swi-prolog 你可以选择其中之一:
显示所有变量的答案替换(默认值)
不显示
_A
等变量的答案替换
有关详细信息,请阅读您正在使用的 Prolog 处理器的手册!
为 SWI: Environment Control (Prolog flags)。
current_prolog_flag/2
。
set_prolog_flag/2
.
stefan@Lenovo ~ $ swipl Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.15) ... ?- current_prolog_flag(toplevel_print_anon, Flag). % get default Flag = true. ?- _A = 1. _A = 1. ?- _A = 1, X = _A. _A = X, X = 1. ?- set_prolog_flag(toplevel_print_anon, false). % toggle flag true. ?- current_prolog_flag(toplevel_print_anon, Flag). Flag = false. ?- _A = 1. % watch out! true. ?- _A = 1, X = _A. X = 1. ?- set_prolog_flag(toplevel_print_anon, true). % restore flag true. ?- current_prolog_flag(toplevel_print_anon, Flag). Flag = true. ?- _A = 1. _A = 1. ?- _A = 1, X = _A. _A = X, X = 1.