Prolog 这行代码到底是做什么的?(序言)

Prolog 这行代码到底是做什么的?(序言),prolog,Prolog,我的讲师给了我们这个示例程序来查看代码,而我对递归函数的理解大体上是这样的,这一行我不能完全理解它的含义 all_different([H | T]) :- member(H, T), !, fail. 从递归函数中提取: all_different([H | T]) :- member(H, T), !, fail. all_different([_ | T]) :- all_different(T). all_different([_]). 我对它的理解是,它将一个列表拆分为一个头H和一

我的讲师给了我们这个示例程序来查看代码,而我对递归函数的理解大体上是这样的,这一行我不能完全理解它的含义

all_different([H | T]) :- member(H, T), !, fail.
从递归函数中提取:

all_different([H | T]) :- member(H, T), !, fail.
all_different([_ | T]) :- all_different(T).
all_different([_]).

我对它的理解是,它将一个列表拆分为一个头H和一个尾T,并检查H是否包含在T中……我的问题是,“!”和“fail”的作用是什么?

这些东西对于Prolog来说是非常基本的

失败
至关重要。它迫使Prolog考虑当前分支失败并启动回溯。
称为“剪切”。它将Prolog提交到当前分支。或者,它在当前规则下修剪选择点的轨迹

结合起来,在Prolog ese中,这表示“如果列表的头部位于列表的尾部,则无需寻找任何其他答案,否则将失败。”因此,如果列表的任何元素位于列表的其余部分,则将立即失败,而不可能回溯。事实上,这并不是那么可怕,它只是意味着Prolog不会再浪费时间试图弄清楚列表是否“完全不同”。回溯将在呼叫站点正常恢复


按这个顺序排列很重要。如果你试图在失败后削减,你就永远无法达到削减目标,因为回溯已经开始了。如果省略cut,则如果列表中有任何子列表满足该属性,则谓词将返回true。最后一个子句保证任何非空列表都是这样,它断言一个具有一个元素的列表满足该属性。如果忽略失败,那么对于子列表中列表的每个元素,您只需要获得一个成功,再加上一个尾部成功。我鼓励您尝试使用谓词,进行这些更改并查看其效果,因为这将大大有助于说明cut-and-fail的目的。

这些内容对于Prolog来说非常重要

失败
至关重要。它迫使Prolog考虑当前分支失败并启动回溯。
称为“剪切”。它将Prolog提交到当前分支。或者,它在当前规则下修剪选择点的轨迹

结合起来,在Prolog ese中,这表示“如果列表的头部位于列表的尾部,则无需寻找任何其他答案,否则将失败。”因此,如果列表的任何元素位于列表的其余部分,则将立即失败,而不可能回溯。事实上,这并不是那么可怕,它只是意味着Prolog不会再浪费时间试图弄清楚列表是否“完全不同”。回溯将在呼叫站点正常恢复

按这个顺序排列很重要。如果你试图在失败后削减,你就永远无法达到削减目标,因为回溯已经开始了。如果省略cut,则如果列表中有任何子列表满足该属性,则谓词将返回true。最后一个子句保证任何非空列表都是这样,它断言一个具有一个元素的列表满足该属性。如果忽略失败,那么对于子列表中列表的每个元素,您只需要获得一个成功,再加上一个尾部成功。我鼓励您尝试使用谓词,进行这些更改并查看其效果,因为这将大大有助于说明剪切和失败的目的