swi-Prolog的过程语义:无法理解结果替换

swi-Prolog的过程语义:无法理解结果替换,prolog,semantics,substitution,Prolog,Semantics,Substitution,我无法理解swi prolog在数据库运行时的行为 打开(a,b)。 查询时使用 :-on(A,B),on(C,D)。 据我所知,应该发生以下情况:首先,查询中最左边的目标与数据库匹配。这将立即成功,导致从查询中删除所述目标以及替换 [A=A,B=B] 接下来,此替换将应用于剩余的目标,该目标不起任何作用,因为第二个目标中既没有A也没有B。现在,剩下的目标与数据库匹配,wich再次成功。现在我们完成了,剩下的应该是换人了 [A=A,B=B,C=A,D=B] 如果我对序言过程语义的理解是正确的,这

我无法理解swi prolog在数据库运行时的行为

打开(a,b)。

查询时使用

:-on(A,B),on(C,D)。

据我所知,应该发生以下情况:首先,查询中最左边的目标与数据库匹配。这将立即成功,导致从查询中删除所述目标以及替换

[A=A,B=B]

接下来,此替换将应用于剩余的目标,该目标不起任何作用,因为第二个目标中既没有A也没有B。现在,剩下的目标与数据库匹配,wich再次成功。现在我们完成了,剩下的应该是换人了

[A=A,B=B,C=A,D=B]

如果我对序言过程语义的理解是正确的,这应该是解释器能够想出的唯一替代方法。不幸的是,swi prolog却不这么认为。相反,它提出了替代方案

[A=C,B=D,C=A,D=B]

如果你非常慷慨,你可以说“两个答案都是一样的”,但当涉及到理解一个程序的功能时,我从来都不慷慨,我是在一个真正重要的上下文中遇到这个问题的。因此,如果有人能帮我弄清楚到底发生了什么,我将不胜感激。

但这两个替换是相同的

我们只能通过事物的相互作用来了解它;对于
substitute(Term,Substitution,substituded_Term)的任何有效实现

因此,这纯粹是一个代表性问题。只要观察结果保持不变,就可以选择任何表示法。

但两种替换法是相同的

我们只能通过事物的相互作用来了解它;对于
substitute(Term,Substitution,substituded_Term)的任何有效实现


因此,这纯粹是一个代表性问题。只要观察到的结果保持不变,就可以选择任何表示法。

接近您想要的输出,但使用常用的Prolog对表示法:

bindings(Query, Bindings) :-
    term_variables(Query, Variables),
    copy_term(Query, Copy),
    term_variables(Copy, VariablesCopy),
    call(Copy),
    pairs_keys_values(Bindings, Variables, VariablesCopy).
电话示例:

?- bindings((on(A,B),on(C,D)), Bindings).
Bindings = [A-a, B-b, C-a, D-b].

唯一的非标准谓词是
pairs\u keys\u values/3
,但这在多个库中都可用。上面我使用了SWI Prolog中的
库(成对)
。Logtalk(您可以在大多数Prolog系统中运行)为库对象提供了一个具有相同语义和参数顺序的谓词。

接近您想要的输出,但使用通常的Prolog对表示:

bindings(Query, Bindings) :-
    term_variables(Query, Variables),
    copy_term(Query, Copy),
    term_variables(Copy, VariablesCopy),
    call(Copy),
    pairs_keys_values(Bindings, Variables, VariablesCopy).
电话示例:

?- bindings((on(A,B),on(C,D)), Bindings).
Bindings = [A-a, B-b, C-a, D-b].

唯一的非标准谓词是
pairs\u keys\u values/3
,但这在多个库中都可用。上面我使用了SWI Prolog中的
库(成对)
。Logtalk(可以在大多数Prolog系统中运行)为库对象提供了一个具有相同语义和参数顺序的谓词。

请注意,结果甚至适用于:

on(a,b).
on2(a,b).

?- on(A,B),on2(C,D).
A = C, C = a,
B = D, D = b.
在任何情况下,写Prolog都会更好

A = C = a,
B = D = b.
这是我之前改编的一张图表。我不知道事情是否是这样实现的,当变量为“fresh”时可能会使用空指针?这不重要


请注意,结果甚至适用于:

on(a,b).
on2(a,b).

?- on(A,B),on2(C,D).
A = C, C = a,
B = D, D = b.
在任何情况下,写Prolog都会更好

A = C = a,
B = D = b.
这是我之前改编的一张图表。我不知道事情是否是这样实现的,当变量为“fresh”时可能会使用空指针?这不重要


就结果的意义而言,毫无疑问,你是对的。然而,prolog解释器如何知道A=C和B=D。如果计算路径如我的开始问题所述,则不应该。在这种情况下,您的问题更多地是语言实现问题。也许它应该这样标记,所以这是清楚的。也许SWI每次在当前替换中添加新绑定时都会执行一些“压缩”步骤;甚至只是在向高层汇报时…@Nestor我们永远不会知道。toplevel可以只打印每个术语一次(它已经在打印输出上缩短列表,grrr),当它遇到引用该术语的另一个变量时,它将只打印变量等式表达式。毫无疑问,就结果的含义而言,您是对的。然而,prolog解释器如何知道A=C和B=D。如果计算路径如我的开始问题所述,则不应该。在这种情况下,您的问题更多地是语言实现问题。也许它应该这样标记,所以这是清楚的。也许SWI每次在当前替换中添加新绑定时都会执行一些“压缩”步骤;甚至只是在向高层汇报时…@Nestor我们永远不会知道。toplevel可以只打印每个术语一次(它已经在打印输出上缩短列表,grrr),当它遇到引用该术语的另一个变量时,它将只打印变量等式表达式。谢谢,这确实有效。因此,我的问题的实际方面得到了解决。然而,我仍然无法理解swi prolog到底是如何推断A=C,B=D的。显然,我对prologs过程语义的想法并不能准确地捕捉到warren Abstract机器(swi prolog引擎盖下的引擎)在做什么。谢谢,这当然行得通。因此,我的问题的实际方面得到了解决。然而,我仍然无法理解swi prolog究竟做了什么来推断A=C,B=D。显然,我对prologs过程语义的想法并没有准确捕捉warren Abstract机器(swi prolog引擎罩下的引擎)正在做什么。第二个输出应该是
[A=C,B=D,C=A,D]