编程中的削减是不好的吗?

10

我这学期正在学习AI课程,其中我们正在学习Prolog。我们的讲师告诉我们尽量避免在作业中使用截断符(cuts),但是对于一些问题,我似乎无法避免使用它们。我只是好奇为什么截断符被认为是一种罪过(讲师的话)?我知道这有点像取巧,但我已经使用了它们,知道它们如何影响我的程序。


4
除了你的程序逻辑变得更难以理解之外,它没有什么特别的问题。可以说,剪切和赋值将你的逻辑程序更接近于命令式程序——如果你希望理解Prolog而不仅仅是通过课程,那么你应该尽量避免这样做。 - Sergey Kalinichenko
5
切割是一种工具,就像其他工具一样,必须根据工作适当选择。您的教练建议不要使用它们,因为新手程序员经常将其用作快速使输出“更整洁”的方法,因为他们不显示实际上可能确实想要看到的解决方案尝试。无意中,他们切断了在不同情况下可能需要的解决方案。因此,不应将其用作“美化”输出的方式,而应作为一个经过仔细考虑的方式来消除逻辑中的选择点。 - lurker
4
如果您遇到一些特定的问题,在那些情况下您觉得必须使用“cut”,请放心在StackOverflow.com上发布这些问题。问出“如何在不用‘cut’的情况下编写这段代码?”这个问题是一个很好的Prolog问题。 :) - lurker
如果您使用剪枝来创建保护条件,那是一种可以接受的优化(甚至是澄清),但是如果剪枝修改可观察的程序行为,则会通过破坏可逆性来破坏逻辑纯度。 - Erik Kaplun
2个回答

10

我同意 @dasblinkenlight 和 @mbratch 的看法。此外,我认为将其分为绿剪枝和红剪枝的概念会有所帮助。

绿剪枝是不影响程序逻辑行为,只影响其性能的剪枝。它们是告诉Prolog,如果继续进行下去,不会有任何结果的方式。绿剪枝从来都不是必需的-它们只是提高了性能。在您首次学习Prolog时,有很多其他内容需要掌握,因此只为获得小幅好处而增加额外的复杂性似乎不太值得。

红剪枝会影响程序行为。正如@mbratch所说,新用户通常会随便使用剪枝以“整理”输出。新用户经常将Prolog查询提示视为其程序的用户界面。这些剪枝使他们的谓词变得不那么通用,也不那么有用,使得输出更加美观。同时还有一些更清晰的替代方法,例如once/1,它可以给您一个单一的结果。专家非常谨慎地使用红剪枝-在某些情况下,它比逻辑方法更有效率-但如果您可以访问纯逻辑公式,则最好使用它。经常使用剪枝错误的谓词在后来依赖该谓词作为其他谓词的一部分时会出现“反向正确性”的问题。这些问题难以调试和修复。

我不确定是否应该称其为“罪过”,但对于初学者,我基本上同意您的教授的看法。最好先通过逻辑方法解决问题,而不使用剪枝。然后,在您更好地了解什么是易于完成和什么是困难之后,可以稍后引入剪枝。在早期过度使用它会使您依赖它作为过程式编程的支撑。


啊,我明白了。我意识到通过使用简便方法,我只是走了捷径,并没有真正弄清楚我的答案是如何产生的。谢谢! - Achaldo
1
很好!这是在Prolog之路上实现重要的领悟。 :) - Daniel Lyons

9
起初,尝试关注Prolog的纯声明部分,原因很简单:这一部分使Prolog区别于其他编程语言。专注于纯粹、单调的语言部分,并完全避免削减。否则,你如何期望深入体验这种编程范式呢?
然而,你肯定会遇到某些挑战,尤其是在尝试编码if-then-else结构和一般性否定时。当这种结构的条件需要成功执行if部分并需要失败执行then部分时,你将进入非单调代码。然而,Prolog从未被设计为以干净的方式处理这样的代码。
相反,Prolog只知道if-then规则。所以,基本上你将为一个部分有一个规则,另一个部分另一个规则。这在一开始看起来可能相当不寻常,但它允许你体验非常纯粹的代码。
请查看我的页面获取纯代码示例。
另请参阅:良好Prolog代码的特点? 好笑的是在SO上总是关闭有趣的问题。
对于绿色或红色削减,请认为几乎没有绿色削减。因为,如果你想以安全的方式使用削减,你将不得不添加其他条件(“guards”),否则它没有任何意义。这确实是优化器、编译器编写者等人需要考虑的事情。
请参阅以下链接:
- 无if和else语句的Prolog - 了解何时在prolog中使用cut - 为什么双重否定在Prolog中不绑定 为了使我的回答更加平衡,在此提供一个使用削减操作符提高效率的干净方法的示例:
- 使用削减操作符的Prolog附加

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接