copyList([], []). % base case
copyList([H|T], [H|R]) :-
copyList(T, R).
我“有点”了解递归的工作原理,但是当我分析此功能时,我真的很困惑。有人可以使用下面的示例逐步说明此功能会发生什么以及如何到达终点:
?- copyList([1,2,3],L).
要了解会发生什么,您必须将Prolog视为一个定理求解器:在向Prolog提供查询时?- copyList([1, 2, 3], L).
,您实际上是在要求Prolog证明其copyList([1, 2, 3], L)
正确。
因此,Prolog将尝试证明这一点。它有两个子句可供使用:
copyList([], []).
copyList([H|T], [H|R]):-
copyList(T, R).
因为它是第一个遇到的问题,所以Prolog会尝试copyList([1, 2, 3], L)
通过使用子句证明这是正确的copyList([], [])
。
为此,由于该子句没有主体(在后面没有:-
),因此只需将查询的参数与该子句的参数统一([1, 2, 3]
与[]
和L
与统一[]
)。虽然很容易统一L5
用[]
(用统一的L5 = []
),不可能统一[1, 2, 3]
用[]
。因此,Prolog无法通过使用第一个子句来证明您的查询。然后,它必须尝试使用第二个。
它将再次使用子句参数统一查询参数,以查看该子句是否适用:在这里,可以通过unifications来实现H = 1, T = [2, 3], L = [H|R]
。现在,它必须查看是否满足下面列出的条件:-
,因此必须证明copyList(T, R)
。完全相同的事情进行了两次,直到发现自己试图证明copyList([], R)
。在那里,第一个子句适用,并且它的工作结束了。
您可以使用图形总结执行情况,如下所示:
copyList([1, 2, 3], L).
|
| try to use clause number 1, doesn't unify with arguments.
| use clause number 2 and L = [1|R]
|
` copyList([2, 3], R).
|
| try to use clause number 1, doesn't unify with arguments.
| use clause number 2 and R = [2|R2]
|
` copyList([3], R2).
|
| try to use clause number 1, doesn't unify with arguments.
| use clause number 2 and R2 = [3|R3]
|
` copyList([], R3).
|
| use clause number 1 and R3 = []. One solution found
| try to use clause number 2, doesn't unify with arguments.
| No more possibilities to explore, execution over.
现在执行结束了,L
通过遵循统一链,我们可以看到原始内容:
L = [1|R]
R = [2|R2]
R2 = [3|R3]
R3 = []
R2 = [3]
R = [2, 3]
L = [1, 2, 3]
感谢威尔·尼斯(Will Ness)关于如何解释变量最终值的初衷。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句