Q.onerror = function(error){
// errors will be here and not thrown in `done` chains.
};
如何使用匿名变量,例如下例中的匿名变量:
append/3
我们实际上只是使用append/2
?
感谢您的回答!
答案 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,也经常使用相同的技术。如果您一致且明智地使用它,它将改善性能和终止属性。