Prolog变量名称

时间:2011-05-01 20:03:45

标签: prolog

例如..

insert(X,Ys,[X|Ys]).
insert(X,[Y|Ys],[Y|Zs]) :- insert(X,Ys,Zs)

为什么使用Zs作为变量..基本情况显然很简单.. X :: YS的头部。 但递归声明将是第一个目标的延续。

所以对于插入(a,[b,c],L)你得到L = [a,b,c] 你第二次得到[b,a,c] 第三次得到[b,c,a]

但是程序中Zs的实际技术定义是什么?

[trace] 1 ?- insert(a,[b,c],L).
   Call: (6) insert(a, [b, c], _G522) ? creep
   Exit: (6) insert(a, [b, c], [a, b, c]) ? creep
L = [a, b, c] ;
   Redo: (6) insert(a, [b, c], _G522) ? creep
   Call: (7) insert(a, [c], _G595) ? creep
   Exit: (7) insert(a, [c], [a, c]) ? creep
   Exit: (6) insert(a, [b, c], [b, a, c]) ? creep
L = [b, a, c] ;

继续是否在重复呼叫时开始?意味着第一个目标结束@基本情况..所以我们下次开始@递归?此外,我可以看到开始使用L的不同变量位置(又名_G522 vs _G595)。

2 个答案:

答案 0 :(得分:1)

Zs是将X插入Ys

的结果

在Prolog中,您通常不会谈到延续,而是选择点。当insert(a,[b,c],L)返回其第一个结果并开始回溯时,Prolog编译器会返回到调用链中以查找最后一个选择点:

  • 最后一个操作是执行insert的第一个子句,该子句是确定性的并绑定L;
  • 在此之前,最后一个操作是在两个子句之间进行选择,这是一个选择点。

因为在这个选择点,选择了第一个子句,所以在回溯时选择第二个子句,导致Zs绑定在谓词中。 L通过从第一个子句回溯而未绑定,并在第二个选项返回时重新绑定。

答案 1 :(得分:0)

Prolog没有延续,但内置了回溯。

说实话,我花了一些时间来理解这个程序。

问题在于Prolog严重依赖于模式匹配,并且当存在多个匹配模式时会插入选择点。如果你想要一个确定性的程序(即没有选择点),你必须确保一次只有一个模式匹配(这是推荐的方式),或者不希望的执行路径在某处失败(这意味着你扔掉了在这里完成的所有计算)路径)。确保一个选择点的最简单方法是使用cut运算符(!/ 0)。

“程序中Zs的实际技术定义是什么?”

在Prolog中,您不必声明变量,它们可以在任何地方引入,并且它们被绑定的地方(获得实际值,这是不可变的)有时很难遵循。如果没有第一个谓词,那么在第二个列表和第二个列表中总会有一个未绑定的变量,但是当在递归调用之后与第一个谓词中的[X | YS]统一时,该变量会被绑定。由于第一个谓词不包含正文,程序终止,并为用户提供解决方案。如你所见,你的程序不能在第二个谓词中终止,只能在第一个谓词中终止,但从递归函数来看并不奇怪,只需要考虑经典的因子示例。

factorial(0,1). 

factorial(N,F) :-  
   N>0, 
   N1 is N-1, 
   factorial(N1,F1), 
   F is N * F1.