好的 Prolog 代码的特点? [英] Features of good Prolog code?

查看:46
本文介绍了好的 Prolog 代码的特点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

What are the design heuristics one has to master to write good Prolog? I've heard it takes an experienced programmer about two years to become proficient in Prolog. Using recursion effectively is part of it, but that seems to be a relatively minor hurdle. What exactly is it that gives programmers so much trouble? What should I be looking for in sample code to judge its quality?

推荐答案

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

The major difficulty in writing good Prolog code lies in not only understanding but also adequately transmitting the intention or purpose of a program. In contrast to other programming languages there are several quite different kinds of Prolog code often within the same program. By confusing such levels bugs and problems ensue:

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

Pure, monotonic code. This code lies at the heart of Prolog. In such code a lot of algebraic properties hold, and the actual problems are described in the pure, ideal manner which Prolog is often advertised with. Yet, even in such parts certain procedural properties may surface, such as non-termination. Take as an example the commutativity of conjunction. In pure, monotonic code, ( A, B ) and ( B, A ) describe the same relation. The only differences may lie in different termination behavior and the sequence how answers appear. Ideally, the names of pure predicates communicate that the predicates are relations. Imperatives are definitely not a good choice here.

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

Side-effectful code. The other extreme is code that can only be understood by effectively executing it, either by machine or in the mind. There are no simple invariants in the program. But even in such parts, there might still be certain properties observed like steadfastness. Effectively such code is not much different to other programming languages.

通常,有副作用的部分会吃掉"纯粹的一面,因为程序员习惯于命令式的、面向命令的 do-this do-that 思维.转向另一个方向,想想你将失去或获得哪些属性.想一想测试你的程序是多么容易:程序越纯越容易在没有任何额外沙箱的情况下进行测试.一个简单的顶级查询就足够了.

Often, the side-effectful part "eats up" the pure side since programmers are used to an imperative, command-oriented do-this do-that thinking. To lean into the other direction, think of which properties you will lose or gain. Think how easy it will be to test your program: The purer a program the easier it is to test without any extra sandbox around. A simple toplevel query is good enough.

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

Some examples, how the pure side can be expanded at the expense of seemingly necessary side-effects:

Prolog 递归跳过相同的结果

或者简单地这些答案.

在您的评论中,您要求学习建议".所以这里有一些:

In your comment, you ask for "advice for learning". So here is some:

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

  1. Stick to writing pure, monotonic code only. You can only judge to choose one or the other side if you know both. I assume you have some previous experience producing side effects in some command-oriented language, but none with pure code. As a consequence this will mean that you will refrain from writing inherently non-monotonic code.

玩顶级.想象一下,顶层是访问您的程序的唯一途径.你会如何制定一个问题,使其适合这种格式?SWI 顶层专门设计用于允许这种轻量级交互.

Play with the toplevel. Imagine, the toplevel is the only way to access your programs. How would you formulate a problem such that it fits into this format? The SWI toplevel has been specifically designed to permit such light-weight interaction.

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

Use clpfd for arithmetics. Don't use (is)/2, it makes your code much too moded.

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

Enjoy the algebraic properties of pure, monotonic code. Think of it: You add a goal, no matter where, and still you can predict that this goal will specialize your program (and at best leaves it as is). You can - blindly - remove a goal, and still you know (part of) its effect.

研究 以掌握非终止.

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

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.

注意你的语言.你谈论一个项目的方式会影响你思考它的方式.因此,如果您使用大量操作性语言(例如:这是这样做的等),您很有可能会强化面向命令的观点.有一种更简洁的谈论事物的方式,但你需要找到它.这可能是最难的部分.

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.

这篇关于好的 Prolog 代码的特点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆