Cut谓词2024 年 8 月 29 日 | 4 分钟阅读 在本节中,我们将提供谓词定义的两个示例。这些定义看起来是正确的,但是当我们使用回溯时,它将会出错。 示例 1在此示例中,我们将使用谓词larger。在前两个参数中,它取较大的值。它将答案作为第三个参数值返回。 在此,我们从“上到下”搜索子句。如果X小于或等于Y,则只会假定第二个子句适用。在以下示例中,前两个参数的值分别为7和5,当我们使用7和5测试该定义时,它会给出如下正确的答案 在此阶段,如果系统被用户强制回溯,它将检查larger的第二个子句,然后生成一个不正确的第二个答案。 示例 2在此示例中,我们将使用sumto/2谓词的定义。此定义看起来是正确的,但是它存在严重的缺陷。 目标sumto(N, S)用于计算从1到N的整数之和。它将结果作为Y的值生成。 如果强制回溯,因此,系统将会崩溃并生成一个神秘的错误消息,例如“堆栈溢出”。当while评估目标sumto(3, S)时,Prolog找到了sumto(1, S)的解决方案。回溯时第一个子句被拒绝。现在,系统使用第二个子句来满足目标。这导致它从1中减去1,然后系统评估目标sumto(0, S)。当系统依次执行此操作时,它将评估sumto(-1, S1),然后评估sumto(-2, S1),然后评估sumto(-3, S1),依此类推。当系统耗尽内存时,此过程将停止。 在谓词的定义中,可以使用附加目标来纠正示例1和示例2。例如,为此,我们将第二个子句中larger的定义更改如下 我们还将第二个子句中sumto的定义更改如下 在其他情况下,识别此类附加术语要困难得多。 使用cut,我们可以避免不必要的回溯。 cut由!表示。在规则的主体中,当!目标第一次评估时,它总是成功。回溯时总是失败。对当前目标的进一步评估总是失败,因此它可以防止这种情况。 示例1(修订版) 示例2(修订版) 当我们对cut使用回溯时,它将放弃对sumto或larger的当前子句的评估。它用于防止评估该谓词的任何其他子句。 示例 3此不正确的程序使用classify/2谓词。此谓词用于对数字进行分类,数字可以是零、正数和负数。在以下程序中,第一个子句处理第一个参数的零值。第二个子句用于处理负值。第三个子句用于处理正值。 通过更改第三个子句,可以按如下方式纠正上述问题 或者,我们也可以使用cut,如下所示 示例3(修订版) 因此,我们已经纠正了所有不正确的程序,而不是使用cut。 我们向其中一个子句添加了一个附加目标。 这种方法比cut好得多。 以下程序显示了一个更困难的案例。 示例 4在以下程序中,我们将使用谓词go。 此谓词用于反复提示用户输入,直到用户输入一个正数。 在谓词classify的定义中,缺少cut会导致不正确的答案。 go的预期行为是通过将classify的定义更改为上面示例3(修订版)中定义的那个来给出的。 示例4(修订版) 下一个主题带失败的Cut |
我们请求您订阅我们的新闻通讯以获取最新更新。