我只想写一个谓词,它包含两个列表:L1
和L2
,并且我希望第三个元素返回{{1}的前一个N
元素},其中L2
是N
的长度。假设我可以假设L1
比L2
长,并且我不想使用内置的L1
,所以我尝试这样做:
length
当我尝试时,它给了我
getFirstPart([],_,_).
getFirstPart([H1|T1],[H2|T2],[H2|T3]) :- getFirstPart(T1,T2,T3).
谁能告诉我出什么问题了?谢谢!
答案 0 :(得分:4)
让我们看一下衍生树。我们从目标开始
getFirstPart([1,1,1],[1,2,3,4,5,6],L).
应用递归规则,我们获得了一个新的目标
getFirstPart([1,1],[2,3,4,5,6],L2).
与L = [1 | L2]
。在下一个递归步骤中会发生相同的情况:
getFirstPart([1],[3,4,5,6],L3).
与L2 = [2 | L2]
。再一次,我们获得
getFirstPart([],[4,5,6],L4).
与L3 = [3 | L4]
。然后,开始执行基本情况。将子替换项放在一起时,得到L = [1,2,3 | L4]
,对L4
无约束。名称_5081628
只是Prolog解释器中L4
的内部名称。
答案 1 :(得分:2)
自由变量归因于基本情况:
getFirstPart([],_,_).
您基本上在这里写:
如果第一个参数为空列表,则我不在乎第二个参数,也不关心第三个参数,它们可以是任何东西。
由于递归案例每次“吃掉”一个元素,最终我们将调用基本案例,因此我们永远不会适当地“关闭”列表。
解决方案是指定最后一个参数的外观:一个空列表,因此:
getFirstPart([],_,[]).
getFirstPart([H1|T1],[H2|T2],[H2|T3]) :-
getFirstPart(T1,T2,T3).
所以我们在这里或多或少地说:
如果第一个参数是空列表,那么我们不在乎第二个参数,但是第三个参数也是空列表。
请注意,在递归情况下,只有一个变量出现一次:H1
,我们可以将其替换为下划线_
:
getFirstPart([],_,[]).
getFirstPart([_|T1],[H2|T2],[H2|T3]) :-
getFirstPart(T1,T2,T3).