什么是最好的Prolog编程实践和风格指南?

Grz*_*ski 13 prolog iso-prolog

好的,我知道这是一个非常普遍的问题,并且已经写了一些关于这个主题的论文,但我觉得这些出版物涵盖了非常基本的材料,我正在寻找更先进的东西来改善风格和效率.这就是我的论文:

  • "研究报告AI-1989-08 Efficient Prolog:A Practical Guide",Michael A. Covington,1989年
  • "高效的Prolog编程",Timo Knuutila,1992年
  • Coomington编写的"Prolog编码指南",Bagnara,O'Keefe,Wielemaker,Price,2011

这些主题涵盖的示例主题包括:尾递归和差异列表,正确使用索引,正确使用剪切,避免断言和缩回,避免CONSing,代码格式化指南(缩进,if-then-elses等),命名约定,代码记录,参数顺序,测试.

您将从Prolog的个人经历中添加什么?是否有适用于CLP编程的特殊风格指南?你知道一些常见的效率问题,知道如何处理它们吗?

更新:

这里有一些有趣的(但仍然太基础和太笼统)点:Lifeware团队的Prolog编程指南

为了突出整个问题,我想问一下"Prolog的编码指南"(Covington等人):

据我们所知,Prolog的一套连贯且相当完整的编码指南从未发布过.此外,当我们查看已发布的Prolog程序的语料库时,我们看不到事实上的标准出现.这一明显遗漏背后的最重要原因是,由于缺乏全面的语言标准,小型Prolog社区进一步分散为以个体Prolog系统为中心的子社区,其中没有一个具有支配地位.

fal*_*lse 13

为了在Prolog中设计干净的接口,我建议阅读Prolog标准,参见.

特别是内置谓词如何编写的具体格式,其中包括特定样式的文档,以及错误信号的发送方式.参见8.1 ISO/IEC 13211-1:1995 的内置谓词定义的格式.您可以在Cor.2Prolog序言中在线找到该样式的定义.

遵循ISO错误信令约定直到字母(但尚未标准化)的库的一个非常好的示例是library(clpfd)SICStus和SWI中的实现.虽然两种实现方法在方法上都有根本的不同,但它们最大限度地利用了错误约定.

回到ISO.这是内置谓词的ISO格式:

xyz名称/精灵

一开始,可能会有一个简短的可选非正式评论.

xyz1描述

给出了一个声明性描述,该描述通常使用描述性变量名称以最常见的目标开始,以便稍后可以引用它们.如果谓词的含义根本不是声明的,则要么声明"是真的",要么使用其他不必要的操作词,如"统一",使用"汇编".让我举个例子:

8.5.4 copy_term/2

8.5.4.1描述

copy_term(Term_1, Term_2)如果Term_2与一个T重命名的副本(7.1.6.2)的术语统一,则为真Term_1.

所以这个统一是一个很大的红色警示标志:不要认为这个谓词是一个关系,它只能在程序上理解.甚至更多(隐含地)它表明定义在第二个论证中是坚定的.

另一个例子:sort/2.这现在是一种关系吗?

8.4.3 sort/2

8.4.3.1描述

sort(List, Sorted)如果SortedList(7.1.6.5)的排序列表统一,则为真.

所以,再一次,没有关系.惊讶吗?请看8.4.3.4示例:

8.4.3.4例子

...

sort([X, 1], [1, 1]).
   Succeeds, unifying X with 1.

sort([1, 1], [1, 1]).
   Fails.
Run Code Online (Sandbox Code Playgroud)

如有必要,添加一个单独的程序描述,从"程序性"开始.它再次没有涵盖任何错误.这是标准描述的一大优势:错误都与"执行"分开,这有助于程序员(内置用户)更系统地捕获错误.公平地说,它会略微增加想要手动优化并逐案优化的实施者的负担.无论如何,这种优化的代码通常容易出现细微的错误.

xyz2模板和模式

这里给出了参数'模式和类型的全面,一或两行规范.该符号非常类似于其他符号,它们起源于1978年的DECsystem-10模式声明.

8.5.2.2模板和模式

arg(+integer, +compound_term, ?term)

然而,ISO的方法与Covington等人的指南之间存在很大差异,该指南仅具有非正式性,并说明程序员应如何使用谓词.ISO的方法描述了内置的行为方式 - 特别是应该预期哪些错误.(上面有4个错误加上一个额外的错误,从上面的规范中看不到,见下文).

xyz3错误

给出了所有错误条件,每个错误条件都在其自己的子条款中按字母顺序编号.7.12错误中的手抄本:

当满足多个错误条件时,Prolog处理器报告的错误取决于实现.

这意味着,每个错误条件必须说明它适用的所有先决条件.他们都是.错误条件不像if-then-elsif那样被读取...

这也意味着编码器必须付出额外的努力才能找到好的错误条件.这完全取决于实际的用户程序员,但对于编码器和实现者来说肯定有点痛苦.

根据8.1.3错误中的NOTES 和7.12.2错误分类(摘要),xyz2中给出的规范直接遵循许多错误条件.对于内置谓词,错误a,b,c,d遵循规范.只有错误e不符合.arg/3

8.5.2.3错误

a)N是一个变量
- instantiation_error.

b)Term是一个变量
- instantiation_error.

c)N既不是变量也不是整数
- type_error(integer, N).

d)Term既不是变量也不是复合词
- type_error(compound, Term).

e)N是小于零的整数
- domain_error(not_less_than_zero, N).

xyz4例子

(可选的).

xyz5 Bootstrapped内置谓词

(可选的).定义其他类似的谓词,它们可以"自举".