gpt4 book ai didi

prolog - 列表操作的奇怪结果

转载 作者:行者123 更新时间:2023-12-04 22:45:52 25 4
gpt4 key购买 nike

我正在尝试在 Prolog 中实现一些用于列表操作的谓词。
一切都按预期工作。例如

append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).

示例查询:
?- append([1,2,3],[4,5,6],X).
X = [1,2,3,4,5,6]. % OK

但是我在使用“删除”谓词时遇到了麻烦。这是它的实现方式:
delete(X,[Y|Ys],Zs) :- X == Y, delete(X,Ys,Zs).
delete(X,[_X|Ys],[_Z|Zs]) :- delete(X,Ys,Zs).
delete(_X,[],[]).

结果不好的示例查询:
?- delete(4,[1,2,3,4],X).
X = [_G8975, _G8978, _G8981]. % BAD

我已经用进一步的输入对其进行了测试,它总是以某种方式返回预期长度的列表。但为什么我只得到那些神秘的 _GXXXX 而不是数字?

提前谢谢了!

最佳答案

你的程序有几个问题。但首先,作为初学者:
坚持 Prolog 的纯单调子集
在您的程序中,您使用的是 (==)/2不再在那个纯子集中。在您的情况下,将其替换为 (=)/2 .
总是看所有的答案
Prolog 的顶级循环仅向您显示第一个答案。你必须按 来要求更多;或空间。您的程序与 (=)/2给出(具有更多可读变量):

?- delete(4,[1,2,3,4],X).
X = [_A,_B,_C] ;
X = [_A,_B,_C,_D] ;
false.
也就是说:不仅第一个答案出乎意料,而且还有第二个答案,其列表长度与原始答案相同。另一方面,第一个答案包括预期的解决方案。所以这个程序太笼统了。
减少输入大小
?- delete(4,[4],L).
L = [] ;
L = [_A] ;
false.
第一个答案现在似乎是正确的,但第二个答案完全出乎意料。也就是说,正如 delete(4,[4],[any]) 所见,该定义过于笼统。
专攻该计划
要本地化该计划,请通过引入诸如 之类的目标来专门化该计划。 false , 和 = 尽可能多,只要 delete(4,[4],[any])成功。我想出了:
?- delete(4,[4],[any]).delete(X,[Y|Ys],Zs) :- false, X = Y, delete(X,Ys,Zs).delete(X,[_X|Ys],[_Z|Zs]) :- X = 4, _X = 4, _Z = any,   delete(X,Ys,Zs).delete(_X,[],[]) :- _X = 4.

Now it should be evident that in this rule, _X =4, _Z = any should be rather the same, and X = 4, _X = 4 should be different. Inequality is best expressed with dif/2.

delete(_X, [], []).
delete(X, [Y|Ys], [Y|Zs]) :-
dif(X, Y),
delete(X, Ys, Zs).
delete(X, [X|Ys], Zs) :-
delete(X, Ys, Zs).
这个定义现在可以以多种方式使用。喜欢
?- delete(X,Xs,[1,2,3]).
Xs = [1, 2, 3],
dif(X, 3),
dif(X, 2),
dif(X, 1) ;
Xs = [1, 2, 3, X],
dif(X, 3),
dif(X, 2),
dif(X, 1) ;
Xs = [1, 2, 3, X, X],
dif(X, 3),
dif(X, 2),
dif(X, 1) ...
请注意,现在有无限多个答案!

关于prolog - 列表操作的奇怪结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26560684/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com