Prolog连接混乱

时间:2017-01-04 15:35:09

标签: prolog

好的,所以我有一些代码可以连接两个列表。代码完全没问题,只是我努力理解代码是如何工作的。

  • 我知道这对你们大多数人来说都是微不足道的。

以下是代码:

conc([],L,L).
conc([H|L1],L2,[H|L3]):-
     conc(L1,L2,L3).

假设我们有2个列表:[3,4,2]和[9,9]我想连接。

Step 1: 
H = 3 
L2 = [9, 9] 
L1 = 4,2

Step 2:
L2  = [9, 9]
H   = 4
L1  = [2]

Step 3:
L2  = [9, 9]
H   = 2
L1  = []

Step 4:
L = [9,9] .... Now why does it not just fail? In my brain [9,9] is not equal to [3, 4, 2]

Step 5:

L2 = L3 = [9, 9]
H   = 2
L1  = []


Step 6:

L2  = [9, 9]
H   = 4
L1  = [2]
L3  = [2, 9, 9]

Step 7:

L2  = [9, 9]
H   = 3
L1  = [4, 2]
L3  = [4, 2, 9, 9]    And done

我发现什么令人困惑?我一定是在看这个错误,L2也只是在递归调用中保持静态,所以我不明白我们通过将第一个输入移动到第三个来实现了什么?

1 个答案:

答案 0 :(得分:2)

在您的第4步中,您没有统一[3, 4, 2][9, 9];您正在使用自由变量统一[9, 9]

您是正确的,步骤3中的绑定是L2 = [9, 9]H = 2L1 = []。请注意L3未绑定!递归调用是conc(L1, L2, L3),因此conc([], [9, 9], L3)。此目标将与conc的第一个子句统一,引入新的绑定L3 = [9, 9]。这是由conc([], L, L)条款引起的,它强制L3L绑定的任何内容统一,在此调用中只有[9, 9]

然后,如您所述,评估将继续进行第5步。

您的Prolog可能有一个可以帮助您理解这一点的示踪剂。在SWI-Prolog中,conc目标看起来像这样(_Gxxxx是自由变量):

?- trace, conc([a,b], [c,d], Xs).
   Call: (7) conc([a, b], [c, d], _G2467) ? creep
   Call: (8) conc([b], [c, d], _G2590) ? creep
   Call: (9) conc([], [c, d], _G2593) ? creep
   Exit: (9) conc([], [c, d], [c, d]) ? creep
   Exit: (8) conc([b], [c, d], [b, c, d]) ? creep
   Exit: (7) conc([a, b], [c, d], [a, b, c, d]) ? creep
Xs = [a, b, c, d].

请注意,输入第三个Call时,变量作为第三个参数,Exit s,该变量绑定到列表。