2009-11-15 135 views
3

如果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只包含整數。Prolog 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。我怎麼說?此代碼確實爲increasingdecreasing,但沒有列表可以是increasingdecreasing

任何想法?

+0

順便說一句,我不允許使用除原始規則和事實以外的任何其他東西。 – DarthVader 2009-11-15 04:48:58

+0

你的導師如何定義「原始規則和事實」? – bcat 2009-11-15 04:51:34

+1

#您可以使用的唯一預定義謂詞是算術/比較,成員/ 2,長度/ 2和附加/ 3(如果不需要,則不需要使用這些謂詞)。 #不要使用任何非聲明性構造。這包括(但不限於)cut(!),assert/retract,not和bagof/setof。 – DarthVader 2009-11-15 04:54:05

回答

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

這工作:)

+0

但在這種情況下,即使是山丘([1,2,3,4,5])也不應該是山丘。 – DarthVader 2009-11-15 05:01:18

+0

看看我編輯的答案是否有幫助。 – bcat 2009-11-15 05:29:50

+0

這絕對有效。 – DarthVader 2009-11-15 06:02:30

2

我不想給一個完整的,工作解決了家庭作業的問題,但我會用言語形容我怎麼會從你得到的代碼進行馬上。現在你的increasingdecreasing謂詞測試整個列表。然而,根據你的定義,一座山並不是完全增加,也不是完全減少。我會修改這些謂詞,使其有兩個參數而不是一個。額外的參數將被綁定到不滿足增加/減少標準的列表尾部。然後,我稍微修改hill以使用increasing的新參數來測試不是整個列表的減小程度,而是測試初始增加子序列之後的部分。最後,我將使用decreasing的新參數來驗證在減少的子序列之後不存在非遞減元素。

如果你需要更好的提示,或者我似乎在說廢話(很可能因爲我對Prolog不太好),請讓我知道,我會試着澄清更多。

根據OP的評論編輯:好吧,讓我們試試其他的東西吧。 L是一個山,當且僅當L是至少兩個單調遞增元素的列表,其以一些元素M結尾,後面是至少一個以某個元素N開始的單調遞減元素的列表,其中N < M。你能把這個描述翻譯成Prolog語句嗎?

編輯需要兩個(擾流警告)


在你的代碼修改,刪除這些三個謂詞:increasing([]).hill([]).hill(List) :- decreasing(List).。這幾乎會給你一個解決方案,但它仍然會失敗,例如在[3, 2, 1]。不過,解決這個問題應該相當容易。

+0

不能有兩個論點,不是教授如何,想要它。無論如何,我明白了,只需要修復一下。謝謝。 – DarthVader 2009-11-15 05:06:12

+0

真的嗎?你不能讓'增加/ 1'和'減少/ 1'進入'增加/ 2'和'減少/ 2'?嗯,這使得它更難一點。讓我想想... – bcat 2009-11-15 05:13:12

1

使用

:- use_module(library(clpfd)). 

我們不必擔心會遞歸的權利,如果我們使用append/3chain/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