10

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

4

1 回答 1

25

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

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

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

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

一些例子,如何以看似必要的副作用为代价来扩展纯粹的一面:

或者干脆这些答案

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

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

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

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

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

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

  6. Do not use a step-by-step tracer/debugger, as it is offered in many Prologs. It only shows you the precise steps Prolog takes. It does not show you anything directly related to the meaning of the program. It reinforces a step-by-step thinking.

  7. Watch your language. The way how you talk about a program influences the way you think about it. So, if you use a lot of operationalizing language (like: This does this etc), chances are you reinforce the command-oriented view. There is a cleaner way of talking about things, but you need to find it. This is probably the hardest part.

于 2013-03-29T19:56:47.723 回答