谓词如何附加/ 3'在Prolog中使用匿名变量?

时间:2015-06-14 21:47:22

标签: prolog

Q.onerror = function(error){ // errors will be here and not thrown in `done` chains. }; 如何使用匿名变量,例如下例中的匿名变量:

append/3

我们实际上只是使用append/2

感谢您的回答!

1 个答案:

答案 0 :(得分:2)

目标

..., append(_,[b(F,ND,P)|Rest],Visited).

读取:

  

Visited个节点列表中的某个位置,有b(F, ND, P)个后续节点Rest

请注意,可能有多个此类节点,因此很可能在某个地方或once/1处有剪切。

  

我们实际上只是使用append / 2?

你在哪里挖出那个骨架 - 图书馆的谓词?但事实上,这可能允许我们实施append/3

myappend(Xs, Ys, Zs) :-
   append([Xs,Ys], Zs).

因此,背后的直觉是与列表Xs连接的列表Ys是列表Zs。从这种陈述的角度来看,显然没有差异。或者是他们?

至少在程序上,差异!对于......

?- append([], Ys, Zs), false.
false.

......终止,但......

?- append([[], Ys], Zs), false.
**LOOPS**

......循环! (在SWI和SICStus中)让我们看看产生的具体答案(我将使用SICStus,因为它更紧凑地打印变量,SWI使用难以读取的变量,如_G1376):

| ?- append([], Ys, Zs).
Zs = Ys ? ;
no

| ?- append([[], Ys], Zs).
Ys = [],
Zs = [] ? ;
Ys = [_A],
Zs = [_A] ? ;
Ys = [_A,_B],
Zs = [_A,_B] ? ;
Ys = [_A,_B,_C],
Zs = [_A,_B,_C] ? ; ....

所以append/3产生了一个答案,而append/2似乎产生了无数的答案。他们如何在声明上等同,或者不是?

答案与解决方案

首先,我要指出上述Ys = [], Zs = []是一个具体的解决方案。接下来是答案Ys = [_A], Zs = [_A],它包含无限多个解决方案。 _A代表无限多的基础术语。因此,有一种方法可以将无限多个解决方案折叠(或提升)为一个优雅而有限的答案。

现在,append([], Ys, Zs)更进了一步,它将所有答案合并为一个:Ys = Zs。但是,这是对的吗?这个答案意味着任何字词都可以是Ys。特别是,non_list,肯定不是列表。想一想:

?- append([a],nonlist,Zs).
Zs = [a|nonlist].

所以append/3有效地做了过度概括解除过多的事情。实际上,它的定义是:

append([], Zs, Zs).
append([X|Xs], Ys, [X|Zs]) :-
   append(Xs, Ys, Zs).

事实是:

  

附有任何东西的空列表,实际上是任何东西(包括所有波兰国王)都是这样的。

显然,这个事实说得太多了。但正是这种过度概括有助于改善终止特性!并且,如果我们有点小心,这种过度概括将永远不会显示出来。 (( 一种阴暗的交易? ))

然而,Prolog享有许多其他属性 - 特别是"单一任务"逻辑变量的属性,可以缓解这个问题。对于差异列表和DCG,也经常使用相同的技术。如果您一致且明智地使用它,它将改善性能和终止属性。