“逻辑纯度"是什么意思?在序言中? [英] What is meant by "logical purity" in Prolog?

查看:12
本文介绍了“逻辑纯度"是什么意思?在序言中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是逻辑纯度"(在 Prolog 编程的上下文中)? 标签信息说仅使用 Horn 子句的程序",但是,像 if_/3 限定,尽可能多地使用它,以及各种元逻辑(什么是正确的术语?var/1 等)谓词,即低级的东西.

What is meant by "logical purity" (in the context of Prolog programming)? The logical-purity tag info says "programs using only Horn clauses", but then, how would predicates like if_/3 qualify, using as much as it does the cut, and the various meta-logical (what's the proper terminology? var/1 and such) predicates, i.e. the low-level stuff.

我知道它实现了一些纯粹"的效果,但这究竟意味着什么?

I get it that it achieves some "pure" effect, but what does this mean, precisely?

如需更具体的说明,请解释 if_/3 如何符合逻辑纯,例如在使用中看到的.在这个答案中?

For a more concrete illustration, please explain how does if_/3 qualify as logically pure, seen in use e.g. in this answer?

推荐答案

让我们先习惯声明式阅读逻辑程序.

Let us first get used to a declarative reading of logic programs.

Prolog 程序以声明方式声明什么是真的.

Declaratively, a Prolog program states what is true.

例如

natural_number(0).
natural_number(s(X)) :-
        natural_number(X).

第一个子句声明:0是一个自然数.

The first clause states: 0 is a natural number.

第二个子句指出:If X 是自然数,then s(X) 是自然数.

The second clause states: If X is a natural number, then s(X) is a natural number.

现在让我们考虑更改此程序的效果.例如,当我们改变这两个子句的顺序时,会发生什么变化?

Let us now consider the effect of changes to this program. For example, what changes when we change the order of these two clauses?

natural_number(s(X)) :-
        natural_number(X).
natural_number(0).

声明式地,交换子句的顺序不会以任何方式改变程序的预期含义(析取是可交换的).

Declaratively, exchanging the order of clauses does not change the intended meaning of the program in any way (disjunction is commutative).

操作上,即考虑到Prolog的实际执行策略,不同的子句顺序显然往往会产生显着的差异.

Operationally, that is, taking into account the actual execution strategy of Prolog, different clause orders clearly often make a signifcant difference.

然而,无论选择的子句顺序如何,都保留了纯 Prolog 代码的一个非常好的特性:

However, one extremely nice property of pure Prolog code is preserved regardless of chosen clause ordering:

如果一个查询Q 成功关于一个子句排序O1,那么Q 不会失败 使用不同的顺序 O2.

If a query Q succeeds with respect to a clause ordering O1, then Q does not fail with a different ordering O2.

请注意,我 不是Q 总是也 succeeds 具有不同的顺序:这是因为查询也可能 循环 或产生不同顺序的错误.

Note that I am not saying that Q always also succeeds with a different ordering: This is because the query may also loop or yield an error with different orderings.

对于 Q1Q2 两个查询,我们说 G1 更一般当它包含 >G2 关于句法统一.例如,查询 ?- parent_child(P, C). 比查询 ?- parent_child(0, s(0))更通用..

For two queries Q1 and Q2, we say that G1 is more general iff it subsumes G2 with respect to syntactic unification. For example, the query ?- parent_child(P, C). is more general than the query ?- parent_child(0, s(0))..

现在,对于纯 Prolog 程序,另一个非常好的属性成立:

Now, with pure Prolog programs, another extremely nice property holds:

如果查询 Q1 成功,那么每个更一般的查询 Q2 都不会失败.

If a query Q1 succeeds, then every more general query Q2 does not fail.

再次注意,Q2 可能会循环而不是成功.

Note, again, that Q2 may loop instead of succeeding.

现在考虑您提到的 var/1 的情况,并考虑相关的谓词 nonvar/1.假设我们有:

Consider now the case of var/1 which you mention, and think of the related predicate nonvar/1. Suppose we have:

my_pred(V) :-
        nonvar(V).

什么时候成立?显然,如果参数不是变量,则它成立.

When does this hold? Clearly, it holds iff the argument is not a variable.

正如所料,我们得到:

?- my_pred(a).
true.

然而,对于更一般的查询?-my_pred(X).,我们得到:

However, for the more general query ?- my_pred(X)., we get:

?- my_pred(X).
false.

这样的谓词称为非单调,由于这个属性,你不能把它当作一个真正的关系:这是因为上面的答案false在逻辑上意味着没有任何解决方案,但在前面的示例中,我们看到解决方案.因此,不合逻辑地,通过添加约束构建的更具体查询会使查询成功:

Such a predicate is called non-monotonic, and you cannot treat it as a true relation due to this property: This is because the answer false above logically means that there are no solutions whatsoever, yet in the immediately preceding example, we see that there is a solution. So, illogically, a more specific query, built by adding a constraint, makes the query succeed:

?- X = a, my_pred(X).
true.

因此,对此类谓词进行推理非常复杂,以至于用它们进行编程一点也不好玩.它使声明式调试变得不可能,并且很难声明任何保留的属性.例如,仅在上述连接查询中交换子目标的顺序就会使其失败:

Thus, reasoning about such predicates is extremely complicated, to the point that it is no fun at all to program with them. It makes declarative debugging impossible, and hard to state any properties that are preserved. For instance, just swapping the order of subgoals in the above conjunctive query will make it fail:

?- my_pred(X), X = a.
false.

因此,我强烈建议留在 Prolog 的纯单调子集内,这允许按照上述思路进行声明性推理.

Hence, I strongly suggest to stay within the pure monotonic subset of Prolog, which allows the declarative reasoning along the lines outlined above.

CLP(FD) 约束、dif/2 等在这个意义上都是 pure 的:你不能欺骗这些谓词给出逻辑上无效的答案,无论模式如何,订单等,您在其中使用它们.if_/3 也满足这个属性.另一方面,var/1nonvar/1integer/1!/0、谓词with side-effects 等都是在逻辑上引用了正在描述的声明性世界之外的东西,因此不能被认为是纯粹的.

CLP(FD) constraints, dif/2 etc. are all pure in this sense: You cannot trick these predicates into giving logically invalid answers, no matter the modes, orders etc. in which you use them. if_/3 also satisfies this property. On the other hand, var/1, nonvar/1, integer/1, !/0, predicates with side-effects etc. are all extra-logically referencing something outside the declarative world that is being described, and can thus not be considered pure.

编辑:澄清一下:我在这里提到的好属性绝不是详尽无遗的.纯 Prolog 代码展示了许多其他非常有价值的属性,通过这些属性您可以感知逻辑编程的荣耀.例如,在纯 Prolog 代码中,添加一个子句最多可以扩展,而不是缩小解决方案的集合;添加一个目标最多可以缩小,从不扩展,等等.

EDIT: To clarify: The nice properties I mention here are in no way exhaustive. Pure Prolog code exhibits many other extremely valuable properties through which you can perceive the glory of logic programming. For example, in pure Prolog code, adding a clause can at most extend, never narrow, the set of solutions; adding a goal can at most narrow, never extend, it etc.

使用一个额外的逻辑原语可能并且通常会破坏许多这些属性.因此,例如,每次您使用 !/0 时,都应将其视为直入纯洁之心的,并为伤害这些属性而感到遗憾和羞耻.

Using a single extra-logical primitive may, and typically will, already destroy many of these properties. Therefore, for example, every time you use !/0, consider it a cut right into the heart of purity, and try to feel regret and shame for wounding these properties.

一本好的 Prolog 书至少会开始引入或包含许多提示,以鼓励这种声明式观点,指导您考虑更一般的查询、保留的属性等.糟糕的 Prolog 书不会对此多说,而且通常最终会使用那些破坏语言最有价值和最美丽属性的不纯语言元素.

A good Prolog book will at least begin to introduce or contain many hints to encourage such a declarative view, guide you to think about more general queries, properties that are preserved etc. Bad Prolog books will not say much about this and typically end up using exactly those impure language elements that destroy the language's most valuable and beautiful properties.

一个很棒的 Prolog 教学环境,它广泛使用这些属性来实现声明式调试,称为 GUPU,我强烈建议您查看这些想法.Ulrich Neumerkel 慷慨地提出了一个在他的环境中使用的核心思想,部分可用作 library(diadem).有关如何以声明方式调试意外失败的目标的一个很好的示例,请参阅源文件:该库系统地构建仍然失败的查询的概括.当然,这种推理完美地使用纯代码.

An awesome Prolog teaching environment that makes extensive use of these properties to implement declarative debugging is called GUPU, I highly recommend to check out these ideas. Ulrich Neumerkel has generously made one core idea that is used in his environment partly available as library(diadem). See the source file for a good example on how to declaratively debug a goal that fails unexpectedly: The library systematically builds generalizations of the query that still fail. This reasoning of course works perfectly with pure code.

这篇关于“逻辑纯度"是什么意思?在序言中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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