Prolog检查列表是否像1,2,3,4,2,1

时间:2011-12-28 00:51:31

标签: prolog

我需要创建一个程序来检查列表是否增加然后减少,就像下面的例子中一样:

[1,2,3,4,5,6,4,3,2,1]

并且必须至少增加或减少一步。

基本上:

  • 必须有一个升序,然后是一个降序。
  • 每个过渡步骤必须至少为一个(并排相同的数字)。
  • 该步骤可以更多而不是一个。

我想到找到列表中的最大数字,然后将列表拆分成两个列表,然后检查它们是否都已排序。如何更轻松地完成?

3 个答案:

答案 0 :(得分:1)

以下是如何做到这一点:

up_and_down([A, B, C|Rest]) :- 
  A < B, up_and_down([B, C|Rest]).
up_and_down([A, B, C|Rest]) :-
  A < B, B > C, goes_down([C|Rest]).
goes_down([]).
goes_down([X]).
goes_down([A, B|Rest]]) :-
  A > B, goes_down([B | Rest]).

第一个谓词检查序列是否正在上升。当我们到达拐点时,第二个是真的。在那之后,我们只需检查它是否会一直持续到最后(最后三个)。

答案 1 :(得分:1)

如果使用的所有数字都是整数,请考虑使用

:- use_module(library(clpfd)).

根据up_down_zs/3,我们可以像这样定义std::getline(annotationsFile, firstLine)

up_down_zs(Up, [P|Down], Zs) :-
   Up = [_,_|_],
   Down = [_|_],
   append(Up, Down, Zs),
   append(_, [P], Up),
   chain(Up, #<),
   chain([P|Down], #>).

首先,我们所有的某些情况会导致失败:

?- member(Zs, [[1,1],[1,2,2,1],[1,2,3,4],[1,2,3,4,5,5,6,4,3,2,1]]),
   up_down_zs(_, _, Zs).
false.

现在,让我们运行一些可以满足的查询!

?- up_down_zs(Up, Down, [1,2,3,4,5,6,4,3,2,1]).
(  Up = [1,2,3,4,5,6], Down = [6,4,3,2,1] 
;  false
).

?- up_down_zs(Up, Down, [1,2,3,1]).
(  Up = [1,2,3], Down = [3,1]
;  false
).

?- up_down_zs(Up, Down, [1,2,1]).
(  Up = [1,2], Down = [2,1]
;  false
).

答案 2 :(得分:0)

或者:

pyramid(L) :-
    append(Increase, Decrease, L),
    (   append(_, [Last], Increase), Decrease = [First|_]
     -> Last > First
     ;  true),       
    forall(append([_, [A, B], _], Increase), A < B),
    forall(append([_, [C, D], _], Decrease), C > D),
    !.

这要求您的实现定义了append/2谓词,例如,如果您使用swi就是这种情况。但使用append/3的改编并不难编码。