这个学期我正在学习一门人工智能课程,我们正在学习 Prolog。我们的讲师告诉我们尽量避免在我们的作业中使用削减,然而,对于一些我似乎无法避免使用它们的问题。我只是好奇为什么削减被认为是一种罪过(讲师的话)?我知道这是一种捷径,但我使用它们确切地知道它们如何影响我的程序。
2 回答
一开始,尝试专注于 Prolog 的纯声明部分,原因很简单:正是这部分将 Prolog 与其他编程语言区分开来。专注于语言中纯粹、单调的部分,完全避免删减。您还能如何期望您沉浸在这种编程范式中?
但是,您肯定会遇到某些挑战。特别是在尝试对 if-then-else 结构和一般否定进行编码时。当这种构造的条件需要在 if 部分成功并且需要在 then 部分失败时,您将进入非单调代码。然而,Prolog 从来没有被构建为以干净的方式处理这样的代码
相反,Prolog 只知道 if-then 规则。所以基本上你会有一个规则用于一个部分,另一个规则用于另一部分。一开始你会觉得这很不寻常,但它可以让你体验到非常纯粹的代码。
有关纯代码的示例,请参见我的页面。
另请参阅:好的 Prolog 代码的特点? 有趣的是,有趣的问题总是在 SO 上结束。
对于绿色或红色切割,简单地认为几乎没有绿色切割是理所当然的。因为,如果你想以安全的方式使用削减,你将不得不添加额外的条件(“守卫”),否则这些条件没有任何意义。对于优化器、编译器编写者等来说,这确实是一件好事。
为了让我的回答更加平衡,这里有一个通过 cut 提高效率的干净方法示例:
我同意@dasblinkenlight 和@mbratch。此外,我认为从绿色切割和红色切割的角度进行思考是有帮助的。
绿切是不影响程序逻辑行为的,只影响性能。它们是您告诉 Prolog 的一种方式,您知道如果它继续运行它不会产生任何结果。从来不需要绿色削减——它们只是提高性能。当你第一次学习 Prolog 时,还有很多其他事情需要处理,这似乎只是为了一点好处而增加了额外的复杂性。
红色切割确实会影响程序的行为。正如@mbratch 所说,新用户经常四处乱砍以“整理”输出。新用户经常将 Prolog 查询提示视为他们程序的用户界面。这些削减使它们的谓词在使输出更好的过程中不那么通用和不那么有用。还有一些更清晰的替代方案,比如once/1
给你一个单一的结果。专家非常巧妙地使用红色切割——在某些情况下它比逻辑方法更有效——但如果你可以使用纯逻辑公式,它会更可取。通常,在使用 cut 时出现错误的谓词会出现“向后正确性”问题,当您将谓词作为其他谓词的一部分时,这些问题会在以后出现。这些可能难以调试和修复。
我不确定我会称它们为“罪过”,但我大多同意你的教授对初学者的看法。如果您在不使用剪辑的情况下逻辑地解决问题方面有经验,那将是最好的。然后,当您更好地了解什么是容易和什么是困难时,可以稍后引入剪辑。过早使用它会使您依赖它作为过程编程的拐杖。