用Prolog中序列的最后一个数字替换连续递减的数字

时间:2016-04-08 04:04:47

标签: list prolog

我一直试图解决这个问题很长一段时间,我认为我尝试的逻辑是有缺陷的。

目标是用子列表的最后一个替换随后减少的数字子列表。

?- compare([1, 3, 7, 6, 5, 10, 9], Result).
Result = [1, 3, 5, 9] ;
false.

我尝试的是:

compare([A,B|T],X):-
       %succ(B,A),
       A is B+1,
       append([],NextX,X),
       compare([B|T],NextX).

remove([A,B|T],X):-
       A=\=B+1,
      compare([B|T],X).

我不确定如何为compare / 2编写基本情况,我认为我没有正确地将我的逻辑转换为代码。我在这里尝试的是比较A和B,如果它们是连续数字,则从列表中删除A. 非常感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

你快到了。首先介绍特殊情况:如果列表只包含一个元素,它就在列表中。

compare([X],[X]).

你的第二条规则只需要改变一下:

compare([A,B|T],X):-       % A is not in the list if
       A is B+1,           % A = B+1
       compare([B|T],X).   % Note: X is the same as in head of rule

你的谓词remove / 2应该是compare / 2的第3条规则,涵盖了另一种情况:

compare([A,B|T],[A|X]):-   % A is in the list
      A=\=B+1,             % if A is not B+1
      compare([B|T],X).

现在查询有效:

   ?-  compare([1, 3, 7, 6, 5, 10, 9], Result).
Result = [1,3,5,9] ? 
yes

但是,只有第一个列表是可变的,才能使用此谓词。你不能反过来使用它:

   ?- compare([A,B,C], [1,2]).
     ERROR at  clause 2 of user:compare/2 !!
     INSTANTIATION ERROR- X is A+B: expected bound value

另一方面,如果你使用库(clpfd)......

:- use_module(library(clpfd)).

compare([X],[X]).
compare([A,B|T],X):-
       A #= B+1,
       compare([B|T],X).
compare([A,B|T],[A|X]):-
       A #\= B+1,
       compare([B|T],X).

...以上查询也有效:

   ?- compare([A,B,C], [1,2]).
A = C = 2,
B = 1 ? ;
A = 1,
B = 3,
C = 2 ? ;
no