消除连续重复

时间:2016-05-22 15:23:27

标签: list prolog prolog-dif logical-purity

消除列表元素的连续重复。

我的解决方案是:

compress([X,X|Xs], Q) :-
   compress([X|Xs], Q).
compress([X,Y|Xs], Q) :-
   X \= Y,
   compress([Y|Xs], QR),
   append([X], QR, Q).
compress([X|[]], Q) :-
   compress([], QR),
   append([X], QR, Q).
compress([], []).

而且,由于我是初学者,而且我没有逻辑范式的经验,我请你说出我可以改进的内容,以及为什么我的解决方案不尽如人意。

例如,X \= Y看起来并不漂亮。

2 个答案:

答案 0 :(得分:5)

我们从谓词的名称开始。

为什么使用命令式来表示关系?一个好的Prolog程序可用于所有方向,而命令式总是建议一个特定的方向或使用模式。因此,请选择声明性名称,并注明通用性和

接下来,最常见的查询是什么:

dif/2

不是很好!我们希望这会产生至少一些答案。

如果我们使用迭代深化怎么办:

?- length(Ls, _), compress(Ls, Cs).
Ls = Cs, Cs = [] ;
Ls = Cs, Cs = [_G841] ;
Ls = [_G841, _G841],
Cs = [_G841] ;
Ls = [_G841, _G841, _G841],
Cs = [_G841] .

嗯!缺少相当多的答案!元素不同的情况如何?正如您已经直观地预期的那样,使用不纯的谓词会导致这种影响。

因此,使用 ,即phrase/2,表示两个词不同。它可以在各个方向使用!

此外,DCG( )在描述列表时通常很有用。

所以,总的来说,这是怎么回事:

compression([])     --> [].
compression([L|Ls]) --> [L], compression_(Ls, L).

compression_([], _) --> [].
compression_([X|Xs], L) -->
        (   { X = L },
            compression_(Xs, L)
        ;   { dif(X, L) },
            [X],
            compression_(Xs, X)
        ).

我们使用接口谓词session_write_close();来处理DCG。

用法示例:

?- phrase(compression(Ls), Cs).
Ls = Cs, Cs = [] ;
Ls = Cs, Cs = [_G815] ;
Ls = [_G815, _G815],
Cs = [_G815] .

?- length(Ls, _), phrase(compression(Ls), Cs).
Ls = Cs, Cs = [] ;
Ls = Cs, Cs = [_G865] ;
Ls = [_G865, _G865],
Cs = [_G865] ;
Ls = Cs, Cs = [_G1111, _G1114],
dif(_G1114, _G1111) .

从这里拿走它!改善决定论,找到更好的名字等。

答案 1 :(得分:4)

the answer by @mat (+ 1)的基础上,为什么不为这样的案例提高确定性

?- phrase(compression([a,a,b,b,b,c,c,c,c,d]), Xs).
Xs = [a, b, c, d] ;
false.

使用 ; false ,SWI 表示目标没有成功确定。

我们可以使用if_//3 - 类似if_/3改善compression_//2

compression_([], _) --> [].
compression_([X|Xs], L) -->
   if_(X = L,                           % is this item equal to previous one?
       compression_(Xs, L),             %   yes: old "run" goes on
       ([X], compression_(Xs, X))).     %    no: new "run" starts

示例查询:

?- phrase(compression([a,a,b,b,b,c,c,c,c,d]), Xs).
Xs = [a, b, c, d].                            % succeeds deterministically