2013-02-07 74 views
0

我有以下Prolog謂詞原型:solution(+ InputVector),其中InputVector是未知長度值的列表。如果列表中的所有值都大於0,我會打印出一條消息。我該怎麼做呢?如何檢查Prolog列表中的每個元素是否大於0?

+0

你已經在你的問題中描述的解決方案... – Lahniep

+0

我是新來的序言和我的教授不是最好的老師,所以我真的只是猜測和測試。這裏是我迄今爲止嘗試過的一個例子: solution([X | Y]): - X> 0.解決方案([_ | Y]): - 解決方案(Y)。 – soccercta100

+0

你沒有處理空列表'[]',如果任何*的數字都大於零,那麼當前你的解決方案將會成功,而不是全部都是。 –

回答

2

嘗試檢查列表是否爲[]或[X | Xs],並相應地採取行動。

+1

我對prolog完全陌生,所以語法本身對我來說完全不熟悉。 – soccercta100

0

你快到了。考慮以下(更新感謝@aBathologist):

1| solution([X]) :- 
    2|  X > 0, 
    3|  !, 
    4|  write_ln('Success!'). 
    5| solution([X|Y]) :- 
    6|  X > 0, 
    7|  solution(Y). 

讓我們考慮這實際上是如何工作的,行由行:

  1. 定義謂詞solution/1的第一條,這需要單元素包含X作爲參數的列表。
  2. 測試項目X是否爲> 0。如果不是,則謂詞將在此處終止並失敗。否則,Prolog將繼續到下一行。
  3. 雖然不是絕對必要的,但是這裏的剪切(!)刪除了Prolog在(1)處生成的選擇點,因爲第(6)行的第二個子句也可能已經使用輸入[X]執行,因爲這是相當於[X|Y]其中Y = []。因此,這僅僅是爲了提高效率而進行的所謂的「格魯吉亞」。
  4. 由於列表[X]包含大於零的元素,所以謂詞打印消息並結束。
  5. 定義謂詞solution/1這需要含有一個或多個物品,其中X是列表的頭部的列表的第二條款,並Y是列表的尾部(餘數)(其本身是一個列表,它可能是空的:[])。
  6. 同第(2)行。
  7. 繼續遞歸測試列表的其餘部分,Y

注意上面的定義假設solution/1只能在數字非空列出大於零成功。如果您希望允許該謂詞對空列表成功,實現可以變得更加簡單:

solution([]) :- 
    write_ln('Success!'). 
solution([X|Y]) :- 
    X > 0, 
    solution(Y). 

在這個版本中,無論是兩個條款solution/1是基於參數執行之一:第一個處理空列表,第二個處理大於零的數字的非空列表。因爲謂詞參數是不可統一的([] \ = [X|Y]),所以在這裏不需要剪切(!),並且Prolog不會爲任何第一個子句的調用生成選擇點。

我希望這對你有幫助,並且使得Prolog語法的一些語義更加清晰。

+0

同樣,如果原始輸入列表爲空,這可能會失敗,這可能不是目的。而且,如果沒有if-then-else,它看起來更乾淨。 –

+1

如果沒有' - >',可以排除空列表:'solution([Val]): - Val> 0,write_ln('Solved')。解決方案([Val | Vals]): - Val> 0解(Vals)'。 –

+0

@aBathologist你是對的,謝謝!我會更新答案,因爲我更喜歡這個,因爲它簡化了描述(特別是對於假設空列表正常的替代方案)。 – sharky

0

我會寫謂詞是這樣的:

all_greater_than_zero([]). 
all_greater_than_zero([H|T]) :- 
    H > 0, 
    all_greater_than_zero(T). 

我認爲一個空表是可以接受的。如果沒有,您可以刪除第一個子句。

+0

如果一個空列表是不可接受的,那麼在你的例子中簡單地刪除第一個子句如果所有元素都是'> 0',允許OP'按照需要打印一條消息'? – sharky

3

,如果你有興趣你的學習擴展到「高階」謂詞考慮maplist/2:

3 ?- maplist(<(0), [1,2,3]). 
true. 

4 ?- maplist(<(0),[0,1,2,3]). 
false. 
相關問題