Prolog - 如何执行返回空列表而不是失败的 setof [英] Prolog - how to do setof that returns empty list instead of failing

查看:38
本文介绍了Prolog - 如何执行返回空列表而不是失败的 setof的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I need an ordered list of Objects that satisfy Goal. setof takes care of the ordering, but fails when no Objects satisfy Goal. I want to return an empty list instead like findall does.

这行得通,但是有没有办法不切分地完成这个任务?我正在使用 SWI-Prolog.

This works, but is there a way of accomplishing this without a cut? I'm using SWI-Prolog.

setof(Object, Goal, List), !; List = [].

推荐答案

首先

..., ( setof(Object, Goal, List), ! ; List = [] ), ...

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

does not work, as you suggest. It always succeeds for List = [], and it only shows the first answer of setof/3. But setof/3 may produce several answers. The general method that works in any Prolog is:

..., ( \+ Goal -> List = [] ; setof(Object, Goal, List) ), ...

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

Many implementations offer an implementation specific control construct for this which avoids that Goal is called twice. E.g. if/3 (SICStus, YAP), or (*->)/2 (SWI, GNU):

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

..., ( setof(Object, Goal, ListX) *-> ListX = List ; List = [] ), ...

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

The new variable ListX is necessary for the (admittedly rare) case that List is already instantiated.

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

这篇关于Prolog - 如何执行返回空列表而不是失败的 setof的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆