【问题标题】:What are the best Prolog programming practices and style guidelines? [closed]最好的 Prolog 编程实践和风格指南是什么? [关闭]
【发布时间】:2014-04-25 20:47:23
【问题描述】:

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

  • “研究报告 AI-1989-08 Efficient Prolog:实用指南”,Michael A. Covington,1989 年
  • Timo Knuutila 的“高效 Prolog 编程”,1992 年
  • “Prolog 编码指南”,Covington、Bagnara、O'Keefe、Wielemaker,Price,2011 年

其中涵盖的示例主题:尾递归和差分列表、索引的正确使用、剪切的正确使用、避免断言和撤回、避免 CONSing、代码格式指南(缩进、if-then-elses 等)、命名约定、代码文档、参数顺序、测试。

根据您对 Prolog 的个人经验,您会在此处添加什么内容?是否有任何仅适用于 CLP 编程的特殊风格指南?您知道一些常见的效率问题并知道如何处理吗?

更新:

这里提出了一些有趣(但对我来说仍然太基本和太笼统)的观点:Prolog programming guidelines of Lifeware Team

为了突出整个问题,我想引用“Prolog 的编码指南”(Covington 等人):

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

【问题讨论】:

  • 必读的书是 Richard O'Keefe 的“The Craft of Prolog”。
  • 这句话来自一组已发布的 Prolog 编码指南……
  • @DanielLyons,我不明白你的评论是什么意思。我正是从引用这句话的地方写的。
  • @GrzegorzAdamKowalski 我认为 Daniel 可能在指出这句话的自我指涉讽刺。
  • 这个问题被一些人搁置为题外话,因为这样的问题“往往会吸引固执己见的答案和垃圾邮件”。好吧,我的目的是吸引自以为是的答案。我应该将此问题移至其他 Stack Exchange Q&A 网站吗?

标签: prolog iso-prolog


【解决方案1】:

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

特别是内置谓词的编码方式的具体格式,包括特定的文档样式以及错误信号的方式。请参阅 ISO/IEC 13211-1:1995 的 8.1 内置谓词定义的格式。您可以在 Cor.2Prolog prologue.

在 SICStus 和 SWI 中实现library(clpfd) 是遵循 ISO 错误信号约定(但尚未标准化)的一个很好的库示例。虽然这两种实现在方法上有根本的不同,但它们都使用错误约定来发挥最大优势。

返回 ISO。这是内置谓词的 ISO 格式:

x.y.z 名称/Arity

​​>

一开始,可能会有一个简短的可选非正式备注。

x.y.z.1 说明

给出了一个声明性描述,该描述通常以最一般的目标开始,使用描述性变量名称,以便以后可以引用它们。如果谓词的含义根本不是陈述性的,则要么声明“是真的”,要么使用一些其他不必要的操作性词,如“统一”、“组装”。举个例子吧:

8.5.4 copy_term/2

8.5.4.1 说明

copy_term(Term_1, Term_2) 为真,当且仅当 Term_2T 合并为 Term_1 的重命名副本 (7.1.6.2)。

所以这个unifies是一个大大的红色警告信号:永远不要认为这个谓词是一个关系,它只能在程序上理解。更重要的是,它(隐含地)声明第二个参数中的定义是坚定的

另一个例子:sort/2。这现在是不是关系?

8.4.3 排序/2

8.4.3.1 说明

sort(List, Sorted) 为真,如果 SortedList (7.1.6.5) 的排序列表一致。

所以,再一次,没有关系。惊讶吗?看8.4.3.4 Examples

8.4.3.4 示例

...

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

sort([1, 1], [1, 1]).
   Fails.

如有必要,将添加一个单独的程序描述,以“程序上”开头。它再次完全不涵盖任何错误。这是标准描述的一大优点:错误都与“做”分开,这有助于程序员(=内置用户)更系统地捕获错误。公平地说,它略微增加了想要手动优化的实施者的负担,并根据具体情况进行优化。无论如何,这种优化的代码往往容易出现细微的错误。

x.y.z.2 模板和模式

在这里,给出了参数模式和类型的全面的一两行规范。该表示法与起源于 1978 年 DECsystem-10 mode declarations 的其他表示法非常相似。

8.5.2.2 模板和模式

arg(+integer, +compound_term, ?term)

然而,ISO 的方法与 Covington 等人的指南之间存在很大差异,后者只是非正式的性质,并规定了程序员应如何使用谓词。 ISO 的方法描述了内置的行为方式——特别是应该预料到哪些错误。 (上面有 4 个错误,还有一个从上面的规范看不到的额外错误,见下文)。

x.y.z.3 错误

给出了所有错误条件,每个都在其自己的子条款中按字母顺序编号。 7.12 Errors中的法典:

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

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

这也意味着编纂者必须付出额外的努力来寻找良好的错误条件。这对实际的用户程序员来说都是有利的,但对于编码者和实现者来说肯定有点痛苦。

根据8.1.3 错误中的注释和7.12.2错误分类x.y.z.2中给出的规范直接遵循许多错误条件/strong> (summary)。对于内置谓词 arg/3,规范中出现错误 a、b、c、d。只有错误 e 没有跟随。

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)

x.y.z.4 示例

(可选)。

x.y.z.5 自举内置谓词

(可选)。 定义其他非常相似的谓词,它们可以被“引导”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-04
    • 2010-12-08
    • 2017-11-26
    相关资源
    最近更新 更多