我无法理解差异列表,特别是在这个谓词中:
palindrome(A, A).
palindrome([_|A], A).
palindrome([C|A], D) :-
palindrome(A, B),
B=[C|D].
任何人都可以帮助我了解正在发生的事情吗?
答案 0 :(得分:7)
palindrome(A, A).
palindrome([_|A], A).
palindrome([C|A], D) :-
palindrome(A, B),
B=[C|D].
将这个谓词的参数看作差异列表,第一个子句说,从A
到A
的列表(即空列表)是回文。
第二个条款说,一个元素列表是一个回文,无论一个元素是什么。
不要惊慌! 差异列表只是带有显式结束“指针”的列表
正常列表,例如[1,2,3]
,是它的开始和结束之间的差异;普通列表的结尾始终是空列表[]
。也就是说,对于列表[1,2,3]
,我们假设将此谓词称为palindrome( [1,2,3], [])
- 即检查是否差异列表{{ 1}}是一个回文。
从操作的角度来看,差异列表只是一个(可能是开放式的)列表,显式维护“结束指针”,例如:[1,2,3] - []
其中{{ 1}}和A - Z
。实际上,A = [1,2,3|Z]
与Z = []
相同。但是当[1,2,3|[]]
尚未实例化时,列表[1,2,3]
仍然是开放式的 - 它的“结束指针”Z
可以被实例化为任何东西(但是只有一次,当然,没有回溯)。
如果我们稍后将A
实例化为开放式列表,例如Z
,我们会得到一个新的扩展差异列表Z
,其中Z = [4|W]
。旧的将成为A - W
,即仍然代表开放式列表A = [1,2,3,4|W]
的前缀A - Z = [1,2,3,4|W] - [4|W]
。一旦关闭,例如使用[1,2,3]
,所有日志对仍然代表其对应的差异列表(即[1,2,3,4 ...]
,W = [5]
...),但A - Z
不再是开放式的,所以不能再延长了。
通常只使用diff列表定义的两个部分作为谓词的单独参数,而不是使用A - W
仿函数。当我们总是使用/处理它们就好像它们是一对中的两个部分时,它们在概念上形成一对。这是一回事。
继续。第三个条款说,A
是一个回文,-
必须是回文,[C|A]-D
必须是A-B
。 B
是列表,[C|D]
是列表的元素。这可能令人困惑;我们改用A, D, B
。此外,使用C
和V
代替Z
和Y
,以提醒我们列表的“结束”:
D
事实上,当B
核心是回文时,在它周围放两个palindrome([V|A], Z):- palindrome(A, Y), Y=[V|Z].
V ................. V ----
^ ^ ^
| | |
| | Z
A Y = [V|Z]
给我们另一个回文。
答案 1 :(得分:0)
以下是一个总结,希望能够提炼出前面讨论的最佳结果,并添加一个小而重要的简化。
首先,应该在手头问题的背景下理解原始问题,可以将其表述为定义Prolog谓词,该谓词将检查列表是回文,还是更一般地产生回文。我们希望使用差异列表探索实现,因此我们可以从以下开始:
% List is a palindrome if List - [] is a palindrome:
palindrome( List ) :- palindrome(List, []).
(如其他地方所述,如果列表List是两个列表的串联 正面和背面,然后前面可以看作是差异 在List和Back之间,也就是说,Front可以被视为等同于(List - Back)。)
要定义回文/ 2,我们从两个“基本案例”开始,一个空列表和一个单例:
% The empty list (L-L) is a palindrome:
palindrome(L, L).
% A singleton list, ([X|L] - L), is a palindrome:
palindrome([X|L], L).
现在让我们转向一般情况。
如果包含多个元素的列表是回文,那么它 将如下所示:E ... E
其中......是(可能是空的)回文。
尾巴,Tail,我们的清单必须如下:E ... E Tail
将这个常规列表写为[E | Rest],我们现在可以看到原始列表([E | Rest] - Tail)是一个回文,如果(Rest - [E | Tail])是回文, 或者根据我们的谓词 palindrome / 2 :
palindrome( [E|Xs], Tail ) :- palindrome(Xs, [E|Tail]).
很容易看出这与原始配方相同。
就是这样!现在,我们可以为回文生成模板:
?- palindrome( X ).
X = [] ;
X = [_G1247] ;
X = [_G1247, _G1247] ;
X = [_G1247, _G1253, _G1247] ;
X = [_G1247, _G1253, _G1253, _G1247]
....