以下代码有效,但我对它如何在幕后做事表示怀疑。例如,在第一次调用Exit(9)时,我不明白c是如何移动到变量O的。这是统一过程的一部分还是完全不同的?关心任何人解释?
concat([], List, List).
concat([Head|[]], List, [Head|List]).
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat([Head], C, Concat).
答案 0 :(得分:1)
您可以“手动”进行统一过程,以验证标记为退出的跟踪线:(9)实际上是'cons-ed'[c]到[x,y,z]:
?- [Head|[]]=[c],List=[x,y,z],[Head|List]=O.
Head = c,
List = [x, y, z],
O = [c, x, y, z].
但是,你不能声称它有效:
?- concat([a,b,c],[x,y,z],L).
L = [a, b, c, x, y, z] ;
L = [a, b, c, x, y, z] ;
...
它没有终止,这清楚地表明了一些问题。第二个子句是冗余的 - 包括行为和语法。它通常写成
concat([Head], List, [Head|List]).
因为空尾列表中的隐式存在于每个列表中 - 除非明确指出尾部:
?- [Head|[]]=[X].
Head = X.
关于行为,您可以从跟踪中看到它是从未使用过的 first 子句。所以,你可以认为它是第一个冗余的 - 也许你添加了第二个因为第三个子句的最后一次调用,其中需要'singleton'列表(我的意思是...,concat([Head], C, Concat).
)。但这样称之为导致非终止问题。更好地简化整个程序,删除第二个条款并简化第三个......