Prolog - 如何做setof返回空列表而不是失败

pra*_*pes 2 prolog prolog-setof

我需要一个满足目标的有序对象列表.setof负责排序,但没有对象满足目标时失败.我想返回一个空列表,而不是像findall.

这有效,但有没有一种方法可以完成这一切没有削减?我正在使用SWI-Prolog.

setof(Object, Goal, List), !; List = [].
Run Code Online (Sandbox Code Playgroud)

fal*_*lse 5

第一,

..., ( setof(Object, Goal, List), ! ; List = [] ), ...
Run Code Online (Sandbox Code Playgroud)

如你所说,不起作用.它总是成功的List = [],它只显示了第一个答案setof/3.但setof/3可能会产生几个答案.适用于任何Prolog的一般方法是:

..., ( \+ Goal -> List = [] ; setof(Object, Goal, List) ), ...
Run Code Online (Sandbox Code Playgroud)

许多实现为此提供了一个特定于实现的控件构造,避免了Goal两次调用.例如if/3(SICStus,YAP)或(*->)/2(SWI,GNU):

..., if( setof(Object, Goal, ListX), ListX = List, List = [] ), ...

..., ( setof(Object, Goal, ListX) *-> ListX = List ; List = [] ), ...
Run Code Online (Sandbox Code Playgroud)

新变量ListX对于List已经实例化的(不可否认的)情况是必要的.

请注意,其他两个答案都不能完全符合您的要求.