用于数字列表的序言模式识别

时间:2018-10-05 07:20:09

标签: prolog pattern-matching

因此,我试图确定是否可以将数字列表识别为算术级数。例如,我有一个数字[5, 10, 15, 20]列表,我需要确定将其识别为算术级数的谓词。

2 个答案:

答案 0 :(得分:2)

我将尝试为您提供一个框架,而不给出全部答案。最重要的是,您应该上网或获得教科书,并学习Prolog递归列表处理。

arith_prog([X,Y|T]) :-
    Diff #= X - Y,
    arith_prog([Y|T], Diff).

arith_prog([_], _). % A single element list is a degenerate arith prog
arith_prog([X,Y|T], Diff) :- ... (what goes here?)

请注意,我在这里使用CLP(FD)(因此是#=/2运算符)。这是在Prolog中使用整数推理的最佳方式,并提供了最通用的解决方案。如果要将其限制为检查完全实例化的数字列表,则可以使用Diff is X - Y

答案 1 :(得分:0)

我们可以很好地找出两个独立数字之间的差异:

diff_between( A, B, C):- 
    C is A - B.

对于列表,我们需要将连续的元素配对

pairs( G3, [A | B], C):-   % G3 is a goal expecting of 3 arguments
    append( D, [_], [A | B]),
    maplist( call(G3), B, D, C).

现在我们可以获取连续元素之间的差异列表:

consec_diffs( L, Diffs):-
    pairs( diff_between, L, Diffs).
 %  pairs( G3,         [A | B], C)
 %  maplist( call(diff_between), B, D, Diffs )

% consec_diffs( [a,b,c, ..., n,m], Diffs)
% =
%              [ b,c, ..., n,m ]
%              [ a,b, ....., n ]
%             ------------------- pairwise diff_between
%      Diffs = [ ............. ]

然后我们只需要找出它们是否都相同:

is_arith_prog( A ):-
    consec_diffs( A, [B | C]),
    maplist( =:=(B), C).

这个答案主要是具有好奇心。它可能会做太多工作。编写任何代码的正确方法是在尽可能少地工作的同时尽快得出结论。在这种情况下,它是通过简单的递归定义以自上而下的方式处理列表来完成的。