Prolog 中 bagof/3 的问题

发布于 2024-11-15 00:35:22 字数 1086 浏览 9 评论 0原文

据我了解,谓词 setof/3 和 bagof/3 可以用来生成问题的解决方案列表。 (链接到 gprolog 手册)

正如预期的那样,以下查询的解决方案是 a、b 和 c。

?- nth(_, [a,b,c], X).                 
X = a ? ;
X = b ? ;
X = c ? ;
yes

现在我尝试这个:

?- setof(X, nth(_, [a,b,c], X), ListOfSolutions).
ListOfSolutions = [a] ? ;
ListOfSolutions = [b] ? ;
ListOfSolutions = [c]
yes

在我看来,解决方案应该是[a,b,c]。我做错了什么?

我正在 Mac OS 上使用 gprolog 1.4.0。


编辑:解决方案

我真正需要的是 (^)/2 运算符,但这里给出的答案是完全正确的,非常感谢您的帮助。如果有人有类似的问题,这里是我当前从 3 维网格中选择单元格的代码。

% selectFLR(?Grid, ?ClassId, ?TDayIdD, ?HourId, -ListOfFLR)
% ---------------------------------------------------------
selectFLR(Grid, ClassId, DayId, HourId, ListOfFLR) :-
    bagof(FLR, ClassId^DayId^HourId^selectSingleFLR(Grid, ClassId, DayId, HourId, FLR), ListOfFLR).

selectSingleFLR(Grid, ClassId, DayId, HourId, FLR) :-
    nth(ClassId, Grid, Class),
    nth(DayId, Class, Day),
    nth(HourId, Day, FLR).

As far as I understand the predicates setof/3 and bagof/3 can be used generate a list of solutions to a problem. (Link to gprolog manual).

As expected the solutions to the following query are a, b and c.

?- nth(_, [a,b,c], X).                 
X = a ? ;
X = b ? ;
X = c ? ;
yes

And now I try this:

?- setof(X, nth(_, [a,b,c], X), ListOfSolutions).
ListOfSolutions = [a] ? ;
ListOfSolutions = [b] ? ;
ListOfSolutions = [c]
yes

The solution should have been [a,b,c] in my opinion. What am I doing wrong?

I am using gprolog 1.4.0 for Mac OS.


Edit: Solution

What I really needed was the (^)/2 operator, but the answer given here was completely correct, thank you very much for your help. If anyone has a similar problem here is my current code to select cells from a 3-dimensional grid.

% selectFLR(?Grid, ?ClassId, ?TDayIdD, ?HourId, -ListOfFLR)
% ---------------------------------------------------------
selectFLR(Grid, ClassId, DayId, HourId, ListOfFLR) :-
    bagof(FLR, ClassId^DayId^HourId^selectSingleFLR(Grid, ClassId, DayId, HourId, FLR), ListOfFLR).

selectSingleFLR(Grid, ClassId, DayId, HourId, FLR) :-
    nth(ClassId, Grid, Class),
    nth(DayId, Class, Day),
    nth(HourId, Day, FLR).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

思慕 2024-11-22 00:35:22

不,不应该。 nth(_,[a,b,c],X) 每次给出 X 的 1 个解。 setof(和 bagof)的工作原理如下:

setof(Things, GoalCondition, Bag)

如果您将 Things 指定为 X,并且 nth/3 中的 X(如上例所示)每次都只是一个变量,setof 将只创建该单个变量的列表。其他可能的统一也是可能的,但每次只会制作一个包含 1 件物品的袋子。

形式:谓词 bagof 和 setof 产生目标中自由变量的单独绑定的集合。 setof 产生没有重复项的集合的排序版本... findall 的作用类似于 bagof,所有自由变量都自动存在量化。另外findall返回一个空列表[]没有目标满足,而bagof失败。

长话短说:使用 findall :P

No, it should not. nth(_,[a,b,c],X) gives 1 solution for X every time. setof (and bagof) work like:

setof(Things, GoalCondition, Bag)

If you specify Things as X, and the X from nth/3 is (as you show in the above example) just a single variable each time, setof will just create a list of that single variable. Other possible unifications will be possible, but it will just make a Bag of 1 item that is in Things each time.

Formal: The predicates bagof and setof yield collections for individual bindings of the free variables in the goal. setof yields a sorted version of the collection without duplicates ... findall acts like bagof with all free variables automatically existentially quantified. In addition findall returns an empty list [] there is no goal satisfaction, whereas bagof fails.

To make a long story short: use findall :P

云醉月微眠 2024-11-22 00:35:22

尝试这样写:

findall((A,B,C,D,E), coursemeetings(A,B,C,D,E),L)

Try writing like this:

findall((A,B,C,D,E), coursemeetings(A,B,C,D,E),L)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文