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].