2011-05-26 27 views
2

我有用prolog語言編寫的這個程序。 問題是,我不明白它是如何工作的。Prolog - 該程序如何工作

even_number([],[]). 
even_number([H|T],S):-even_number(T,W),Z is H mod 2,Z==0,S=[H|W]. 
even_number([_|T],S):-even_number(T,S). 

它只是從列表中提取偶數並將其存儲到另一個列表中。 我知道它使用遞歸,但我不能理解在執行過程中所做的步驟。 任何人都可以解釋嗎?

+2

Ted的回答很好,但是嘗試將該程序保存到文件中,啓動一個prolog解釋器,加載程序('[filename] .'),開始跟蹤(使用trace.'),然後調用'even_number'統治與清單。在試圖瞭解它的工作原理時,逐步看到它的執行是非常有用的。 – 2011-05-26 01:15:11

回答

2

該程序包含三個作爲一組應用的規則。他們一起工作基本上是if ... else if ... else if ... [else fail]

第一條規則是:空列表中的偶數是空列表。這很簡單。

如果第一個規則失敗(即第一個參數不是空列表),則應用第二個規則。這有點複雜,但基本上說包含列表的第一個元素,如果它是偶數。邏輯分解如下。以H開頭且尾部爲T的列表中的偶數爲S如果右側的所有項均爲真:T中的偶數爲某個列表W; Z是將H除以2後的餘數;那Z是零;那SH其次是W(不管W竟然是)。 (請注意,如果第一項移至Z==0後,此規則將更有效。)

如果該規則失敗(即,H爲奇數),則應用最後一條規則:應用最後一條規則:列表是列表尾部的偶數。

0

它寫得不好。

even_numbers(X , R) :- 
    even_numbers(X , [] , T) , 
    reverse(T , R). 

even_numbers([] , T , T). 
even_numbers([X|Xs] , T , R) :- 
    Z is X mod 2 , 
    Z == 0 , 
    ! , 
    even_numbers(Xs , [X|T] , R). 
even_numbers([_|Xs] , T , R) :- 
    even_numbers(Xs , T , R). 

第一個謂語,謂語even_numbers/2是大衆的包裝:如果你重構它一點,使它尾遞歸可能更容易理解。它調用私人助手even_numbers/3,它以相反的順序回傳偶數列表。它將其逆轉並試圖將其與包裝器中傳遞的結果統一起來。 的輔助方法做到這一點:

  • 如果源列表爲空:統一所述蓄能器(T)與所述結果。
  • 如果源列表不爲空,並且該列表(X)的頭部是偶數,
    • 遞歸向下列表(XS)的尾部,推X到累加器。
  • 如果源列表不爲空,並且該列表(X)的頭部是奇數,
    • 遞歸向下列表(XS)的尾部,而無需修改累加器。

但正如@安德烈Paramés指出,通過它在調試工作,便清楚發生了什麼事情。