我参加了一门课程,在其中学习了一些序言。我不知道如何/何时使用剪切。尽管我了解了剪切的一般概念,但我似乎无法正确使用它们。
任何人都可以简要解释一下或提供一个关于他们可以推荐的“剪辑”的好教程(不是 learnprolognow.org)吗?
TL;DR: Don't.
剪切修剪了 Prolog 的搜索树。也就是说,给定一个没有剪切的纯 Prolog 程序和带有剪切的相同程序,唯一的区别是带有剪切的程序可能会在无结果的分支上花费更少的时间,因此效率更高;可能会有更少的答案;它也可能终止,而原始程序则不会。
听起来很无害……甚至很有用,不是吗?
嗯,大多数时候事情都比较复杂。
Red cuts
剪辑的使用方式常常使得没有剪辑的程序根本没有任何实际意义。这种切割称为红色切割。在更好的情况下,它用于实现非单调否定的原始形式。而在其他一些情况下,一半是否定,一半是一些很难理解的程序意义。不仅对于程序的读者,而且对于程序的作者也是如此。事实上,此类用途往往无意中缺乏坚定。无论如何:这些削减不是placed到现有程序中。他们从一开始就应该参与该计划。
对于这种红色切割的更结构化的用途,更好地使用once/1
, (\+)/1
, or (;)/2
– if-then-else 之类( If -> Then ; Else )
反而。更好的是,尝试通过发出以下命令来防止此类构造被意外使用instantiation_error
s。或者使用iwhen/2 https://stackoverflow.com/a/40449516/772868这会产生实例化错误或when/2
(在 SWI、YAP、SICStus 中提供)会延迟目标。
绿色削减
Cuts that remove useless choicepoints (and also redundant answers) are called green cuts. But beware: You cannot place them into your program simply pressing ! and some #00ff00
. Most of the time you need a clean read-only guard to ensure that there is no way this cut turns #ff0000
. There is also a simple way to remove some leftover choicepoints safely: call_semidet/1 https://stackoverflow.com/a/12942551/772868. Here are some related cases:
此查询的 SLD 树是什么? https://stackoverflow.com/questions/13162803/whats-the-sld-tree-for-this-query/13165981
Prolog 附加与剪切运算符 https://stackoverflow.com/questions/11360026/prolog-append-with-cut-operator/12710995#12710995
后继算术和的最佳绿色切割是什么? https://stackoverflow.com/questions/13300231/what-are-the-optimal-green-cuts-for-successor-arithmetics-sum/13311382#13311382
在 Prolog 中实现“last” https://stackoverflow.com/questions/11734986/implementing-last-in-prolog/11736042#11736042
剪切不是提交
最后,让我指出 cut 不是提交运算符。有时它的行为有点像它,但需要很多限制才能成为其中之一。提交操作符不能被(滥用)用来实现(\+)/1
。提交要求每个子句彼此独立地进行尝试。因此,每个子句都需要一个完整的保护;它不能依赖于仅在先尝试其他一些条款之后才进行尝试。此外,谓词的每个子句中都必须发生提交。切割可以发生在任何地方。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)