gpt4 book ai didi

prolog - 通过示例(Prolog 语言)理解 Cut(!) 运算符的问题

转载 作者:行者123 更新时间:2023-12-04 02:11:47 25 4
gpt4 key购买 nike

我有以下规则:

noRepetition([]).
noRepetition([Elem|Rest]):- not(member(Elem,Rest)), !, noRepetition(Rest).

此规则用于确定列表中是否没有重复元素,成员规则决定特定元素是否属于列表。我的问题与此规则中的 cut 运算符有关,因为我不确定它的作用。

我已经为 ?-noRepetition([a,b,b,c,d]) 绘制了以下跟踪并且遇到了一个问题(可能与我对剪切运算符):

?-noRepetition([a,b,b,c,d])
Unfies with the second noRepetion rule and instantiates variables to:
noRepetition([a|b,b,c,d] :- not(member(a,[b,b,c,d])), !, noRepetition([b,b,c,d]).

现在我被卡住了,因为在这种情况下 not member 返回 true,因此 cut 被证明是 true,但是我不确定这个 cut 是否会阻止程序进入 noRepetition(第三个目标)或者它是否做了其他事情。如果它确实阻止了程序进入 noRepetition,那么该规则将被评估为 true,但情况并非如此,因为列表中存在重复。

最佳答案

针对您的问题。我的意见:削减是不必要的。您可能想重温一下剪辑的作用; here is a short summary .一个好的经验法则是查看晋级前的最后一个进球,看看它是否留下了选择点。如果是这样,那么它们都会被丢弃(连同本条款主体中早期目标的所有选择点),你只剩下第一个解决方案。所以我们看:

\+ member(Elem, Rest) % just another way to say not...

这什么时候能留下一个选择点?如果 Goal 为假,则 \+ Goal 为真,否则为假。据我所知,\+ Goal 永远不会多次为真,也不会多次为假。那你为什么需要切割?它在这种情况下是多余的,实际上什么都不做。

(我还是想知道为什么你一开始就把 cut 放在那里。是否有类似的谓词没有在 member/2 上使用否定?)

提问者不赞成提供更好的解决方案,但有 at least two other ways解决这个问题。您甚至可以将它们混合在一起以获得以下定义:

all_dif_list(L) :-
( ground(L)
-> sort(L, S),
length(L, N),
length(S, N)
; all_dif_list_nonground(L)
).

all_dif_list_nonground([]).
all_dif_list_nonground([X|Xs]) :-
maplist(dif(X), Xs),
all_dif_list_nonground(Xs).

如果您知道该列表已完全实例化,则可以对其进行排序并比较长度。 sort/2 删除重复项,因此如果有重复项,排序后的列表会更短。

如果列表包含变量,安全的做法是只说列表中的每一对元素(并且将永远)不同。

请记住,member/2 比其简单的名称和直接的定义所暗示的要复杂得多。如果我认为我会从中受益,我可以轻松地写一篇关于 member/2 行为的 1000 字文章。

关于prolog - 通过示例(Prolog 语言)理解 Cut(!) 运算符的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37356113/

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