Prolog 序言串接混淆

Prolog 序言串接混淆,prolog,Prolog,好的,我有一些连接两个列表的代码。代码根本没有问题,只是我在努力理解它是如何工作的 我知道这对你们大多数人来说都是微不足道的 代码如下: conc([],L,L). conc([H|L1],L2,[H|L3]):- conc(L1,L2,L3). 假设我们有两个列表:[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:

好的,我有一些连接两个列表的代码。代码根本没有问题,只是我在努力理解它是如何工作的

  • 我知道这对你们大多数人来说都是微不足道的
代码如下:

conc([],L,L).
conc([H|L1],L2,[H|L3]):-
     conc(L1,L2,L3).
假设我们有两个列表:[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在整个递归调用过程中都是静态的,所以我不明白我们从第一个输入移动到第三个输入实现了什么?

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

步骤3中的绑定是
L2=[9,9]
H=2
L1=[]
,这是正确的。请注意,
L3
未绑定!递归调用是
conc(L1,L2,L3)
,因此
conc([],[9,9],L3)
。这个目标将与
conc
的第一条统一,引入新的绑定
L3=[9,9]
。这是由于子句
conc([],L,L)
,它强制
L3
L
绑定到的任何对象相统一,在这个调用中,该对象就是
[9,9]

然后按照您描述的步骤5进行评估

您的序言可能有助于您理解这一点的跟踪程序。在SWI Prolog跟踪中,
conc
目标如下所示(
\u Gxxxx
是自由变量):


请注意,第三个
调用
是以一个变量作为第三个参数输入的,而
退出
s则将该变量绑定到一个列表。

步骤4不会失败,因为您正在将
conc([],L,L)
conc([],[9,9],L)
统一,这只会产生
L=[9,9]
。你为什么认为这会失败<代码>[3,4,2]在这个统一步骤的任何地方都不会出现。
?- 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].