考虑以下定义:
my_append([], L, L).
my_append([H|T], L, [H|NewTail]):-
my_append(T, L, NewTail).
以及可能的用法及其输出:
?- my_append([1,2,5], [3,4], L).
L = [1, 2, 5, 3, 4].
有人可以帮助我了解它是如何工作的吗?
这项工作就像一个递归函数。定义递归函数 my_append(A,B,C) 有两个步骤 (1&2),它采用两个列表 A 和 B 并构建一个列表,该列表是 A 和 B 的元素的附加(称为此结果 C)。这里第三个参数作为函数的结果(不是真的,而是一个很好的第一近似值)。
1) 基本情况。 my_append([], L, L)。
在第一个 Liste 为空的情况下,结果是可以放入第二个参数的所有内容。
2)递归情况。 my_append([H|T], L, [H|NewTail]):- my_append(T, L, NewTail)。
在第一个列表不为空的情况下,第一个列表的形式为 [Head|Tail],我们希望该头部成为我们结果的头部(第三个参数)。第二行详细介绍了如何构建结果的结尾/结尾。结果的结尾/结尾是缩短的第一个 arg 和第二个 arg 的附加:这是递归;问题是使用它自己的定义来表达,但在一个列表中,女巫是一个较短的元素。
所以日复一日,第一个 arg 越来越短,直到基本情况匹配。
请注意,如果您使用未绑定变量的参数调用 my_append()(如果您愿意,请知道变量),那么结果可能是不确定的:也就是每次调用都将返回不同的解决方案,直到没有更多的解决方案。
我这样称呼方法:
my_append([1,2],[3,4],L)
它匹配
my_append([1,2],[3,4],[1,2,3,4])
it's logicals implication are given by :
my_append([1,2],[3,4],L) => match 2)
so the reduction is :
my_append([1,2],[3,4],[1,I])
where my_append([2],[3,4],I) must be reduce.
my_append([2],[3,4],I) => match 2)
so the reduction is :
my_append([2],[3,4],[1,2,J])
where my_append([],[3,4],J) must be reduce.
my_append([],[3,4],K) => match 1)
so the reduction is :
my_append([],[3,4],[3,4]) where all variables are know/bind.
所以我们“去堆栈”
K = [3,4] (base case)
J = [3,4] (recursion case)
I = [2,3,4] (recursion case)
L = [1,2,3,4] (call)
这是一个递归函数。
它将第一个列表拆分为头块,当它为空时,它获取第二个列表并连续将头添加到前面。
您可以将其想象为对 my_append 的多次调用,如下所示:
my_append([1,2,5], [3,4], L)
调用:
my_append([2,5], [3,4], L)
调用:
my_append([5], [3,4], L)
然后调用基本情况:
my_append([], [3,4], L)
然后以相反的顺序返回,如下所示:
L为[3,4],则L为[5,3,4],则L为[2,5,3,4],则L为[1,2,5,3,4],函数结束.