2011-12-28 35 views
1

我需要创建一个程序来检查,如果列表增大后减小,就像在下面的例子:Prolog的支票像1,2,3,4,2,1

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

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

基本上:

  • 必须有一个单一的递增序列,随后由单递减的序列。
  • 每个转换中的步骤必须至少有一个(并排没有相同的数字)。
  • 该步骤可以是以上以上。

我想过要找到列表中最大的数字,然后将列表拆分成两个列表,然后检查它们是否都被排序。它怎么做更容易?

+0

您是否缺少标题中的“3”和示例中的“5”?另一个问题:序列必须以相同的数字开始和结束? – angus 2011-12-28 00:55:34

+0

@ user1118501,试图根据我的理解澄清规则,请让我们知道他们是否是错误的。 – paxdiablo 2011-12-28 01:00:03

+0

有没有错误!我需要的是一个谓词来检查一个列表最初是否增加,并在一个点减少后。我们不需要按照 – user1118501 2011-12-28 01:51:06

回答

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]). 

第一个谓词检查。当我们达到拐点时,第二个是真的。之后,我们只需检查它是否下降到最后(最后三个)。

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的改编并不难。

1

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

 
:- use_module (library(clpfd)). 

基于chain/2,我们可以定义up_down_zs/3这样的:

 
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 
). 
+1

的顺序排列数字你是否详细说明了'up_down_zs(Up,Down,[1,1])'? – false 2015-08-11 19:16:17