了解差异列表(Prolog)

时间:2013-11-24 00:59:59

标签: prolog palindrome difference-lists

我无法理解差异列表,特别是在这个谓词中:

palindrome(A, A).
palindrome([_|A], A).
palindrome([C|A], D) :-
   palindrome(A, B),
   B=[C|D].

任何人都可以帮助我了解正在发生的事情吗?

2 个答案:

答案 0 :(得分:7)

palindrome(A, A).
palindrome([_|A], A).
palindrome([C|A], D) :-
   palindrome(A, B),
   B=[C|D].

将这个谓词的参数看作差异列表,第一个子句说,从AA的列表(即空列表)是回文。

第二个条款说,一个元素列表是一个回文,无论一个元素是什么。


不要惊慌! 差异列表只是带有显式结束“指针”的列表

正常列表,例如[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-BB是列表,[C|D]是列表的元素。这可能令人困惑;我们改用A, D, B。此外,使用CV代替ZY,以提醒我们列表的“结束”:

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] 
....
相关问题