如果IntList由单调递增的>整数后跟单调递减的整数组成,则hill(+ IntList)成功。例如,> [1,2,5,8,11,6,3,-1]是一个小山,但是[1,2,5,8,11,6,9,3,-1]和[ 1,2,3,4,5,6]>不是丘陵。您可以假设IntList只包含整数。
这是我到目前为止所做的:
hill(List) :-
increasing(List), decreasing(List).
increasing([H|Tail]) :-
sm(H,Tail),
increasing(Tail).
increasing([]).
decreasing([H|Tail]) :-
gr(H,Tail),
decreasing(Tail).
decreasing([]).
hill([]).
gr(X,[H|Tail]) :- X>H.
gr(X,[]).
sm(X,[H|Tail]) :- X<H.
sm(X,[]).
但这不起作用。逻辑是:如果是hill
,那么数字列表为increasing
,然后是decreasing
。怎么说呢?此代码执行increasing
和decreasing
,但没有列表可以同时为increasing
和decreasing
。
有什么想法吗?
答案 0 :(得分:2)
我不想为作业问题提供完整,有效的解决方案,但我会用语言描述如何从你现在获得的代码开始。现在,您的increasing
和decreasing
谓词会测试整个列表。但是,根据你的定义,山丘既不是完全增加也不是完全减少。我会修改这些谓词,使其有两个参数而不是一个。附加参数将绑定到列表的尾部,该尾部不满足增加/减少标准。然后,我稍微修改山丘以使用increasing
的新参数来测试整个列表的减少度,而不是初始增加子序列之后的部分。最后,我将使用decreasing
的新参数来验证在递减子序列之后没有非递减元素。
如果你需要更好的提示,或者我似乎在说废话(很可能因为我对Prolog不太好),请告诉我,我会尝试澄清更多。
根据OP的评论进行编辑:好的,让我们尝试别的。 L
是一个小山,当且仅当L
是至少两个单调递增元素的列表,以一些元素M
结尾,后跟至少一个单调递减元素的列表,以一些元素N
,其中N < M
。你能将这个描述翻译成Prolog条款吗?
编辑带两个(SPOILER WARNING):
在修订后的代码中,删除以下三个谓词:increasing([]).
,hill([]).
和hill(List) :- decreasing(List).
。这几乎可以为您提供解决方案,但它仍然会失败,例如在[3, 2, 1]
。但是,解决这个问题应该相当容易。
答案 1 :(得分:1)
使用clpfd!
:- use_module(library(clpfd)).
如果我们像这样使用append/3
和chain/2
,我们就不用担心收到正确的递归:
hill(Zs) :-
Ascending0 = [_|_],
Descending = [M,_|_],
append(Ascending0,Descending,Zs),
append(Ascending0,[M],Ascending),
chain(Ascending ,#<),
chain(Descending,#>).
让我们运行OP给出的查询!
?- hill([1,2,5,8,11,6,3,-1]).
true % as expected
; false.
?- hill([1,2,5,8,11,6,9,3,-1]).
false. % as expected
?- hill([1,2,3,4,5,6]).
false. % as expected
答案 2 :(得分:0)
hill(L1) :- concatenate(L2,L3,L1), inc(L2), dec(L3).
dec([X|[Y|[]]]) :- X > Y.
dec([X|[Y|L]]) :- X > Y, dec([Y|L]).
inc([X|[Y|[]]]) :- Y > X.
inc([X|[Y|L]]) :- Y > X, inc([Y|L]).
concatenate([],L2,L2).
concatenate([X|L1],L2,[X|L3]) :- concatenate(L1,L2,L3).
这有效:)