【问题标题】:Features of good Prolog code? [closed]好的 Prolog 代码的特点? [关闭]
【发布时间】:2013-03-29 19:04:15
【问题描述】:

要编写好的 Prolog,必须掌握哪些设计启发式方法?我听说一个有经验的程序员需要大约两年的时间才能精通 Prolog。有效地使用递归是其中的一部分,但这似乎是一个相对较小的障碍。究竟是什么给程序员带来了这么多麻烦?我应该在示例代码中寻找什么来判断它的质量?

【问题讨论】:

标签: prolog failure-slice logical-purity


【解决方案1】:

编写好的 Prolog 代码的主要困难不仅在于理解,而且在于充分传达程序的意图或目的。与其他编程语言相比,在同一个程序中通常有几种完全不同的 Prolog 代码。通过混淆这些级别,错误和问题随之而来:

纯粹、单调的代码。 这段代码是 Prolog 的核心。在这样的代码中,许多代数属性都成立,实际问题以 Prolog 经常宣传的纯粹、理想的方式描述。然而,即使在这样的部分中,某些程序属性也可能会出现,例如不终止。以合取的交换性为例。在纯粹的单调代码中,( A, B ) 和 ( B, A ) 描述了相同的关系。唯一的区别可能在于不同的终止行为和答案出现的顺序。理想情况下,纯谓词的名称表明谓词是关系。命令式在这里绝对不是一个好的选择。

有副作用的代码。 另一个极端是只有通过机器或大脑有效执行才能理解的代码。程序中没有简单的不变量。但即使在这样的部分,可能仍会观察到某些特性,如坚定不移。实际上,这样的代码与其他编程语言没有太大区别。

通常,副作用部分会“吞噬”纯粹的一面,因为程序员习惯于命令式、面向命令的“做这个做那个”的思维方式。要转向另一个方向,请考虑您将失去或获得哪些属性。想想测试你的程序是多么容易:一个程序越纯,在没有任何额外沙箱的情况下就越容易测试。一个简单的顶级查询就足够了。

一些例子,如何在牺牲看似必要的副作用的情况下扩展纯粹的一面:

或者只是these answers。

编辑:在您的评论中,您要求“学习建议”。所以这里有一些:

  1. 坚持只写纯粹的、单调的代码。如果你都知道,你只能判断选择一方或另一方。我假设您以前有一些使用某些面向命令的语言产生副作用的经验,但没有使用纯代码的经验。因此,这意味着您将避免编写固有的非单调代码。

  2. 玩顶级游戏。想象一下,顶层是访问您的程序的唯一途径。你将如何制定一个适合这种格式的问题? SWI 顶层经过专门设计,可实现这种轻量级交互。

  3. 使用 进行算术运算。不要使用(is)/2,它会让你的代码过于模仿。

  4. 享受纯单调代码的代数特性。想一想:您添加了一个目标,无论在哪里,您仍然可以预测该目标将使您的程序专业化(并且最多保持原样)。你可以——盲目地——删除一个目标,但你仍然知道(部分)它的影响。

  5. 研究 的概念以掌握不终止。

  6. 不要使用分步跟踪器/调试器,因为它在许多 Prolog 中都提供。它只向您显示 Prolog 采取的精确步骤。它没有向您显示与程序含义直接相关的任何内容。它强化了循序渐进的思考。

  7. 注意你的语言。你谈论程序的方式会影响你思考它的方式。因此,如果您使用大量可操作性语言(例如:This does this 等),您可能会强化面向命令的视图。有一种更简洁的谈论事物的方式,但你需要找到它。这可能是最难的部分。

【讨论】:

  • 你是说主要的困难是知道何时以命令式或声明式的方式使用 Prolog 来解决特定的子问题?我希望这些知识来自对特定系统和特定问题的大量经验。所以我想你不能给出太多关于学习的一般性建议。
  • @user287424:我提出了一个问题:您将失去或获得多少财产?测试代码有多容易?这也可以为您回答,尽管需要一些时间来详细考虑。经验使这当然更容易和更快,但您可以从这里开始。
  • @j4nbur53 单调性和坚定性并不总是相关的。以append/3的第一个论点为例:它不坚定,但定义仍然是单调的。
  • @j4nbur53:您正在评论“学习建议”。没有议程。
  • 如果您需要一个大域名来证明您的观点,请选择:7^7^7#>= abs(X)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-28
  • 2011-05-18
  • 2010-11-04
  • 1970-01-01
相关资源
最近更新 更多