程序中有一個小錯誤開始 - 行Total = Head + Sum
意味着Total
是一個結構+
有兩個參數。您可能的意思是is
,而不是=
,意思是算術評估。但最好是用#=
代替。
在你的問題你問什麼程序將做。在面向命令(「命令式」)的語言中,這是一個相當合理的問題,因爲您可以從程序中脫離出來的唯一含義就是它的分步操作。但是在Prolog中,情況有點不同。你仍然可以嘗試應用這種循序漸進的思維方式,但遲早你會意識到事情會變得非常複雜,這是因爲Prolog沒有一個控制流,而是兩個同時調用(AND-和OR-控制)。甚至「數據結構」也是不同的......
但是有一種方法可以讀取Prolog程序,它在命令式語言中沒有對應部分:您可以將程序理解爲參數之間的關係。通過這種方式,您可以專注於關係看起來像什麼,而不是程序方面。畢竟,如果描述的關係是錯誤的,那麼詢問程序如何做到這一點是毫無意義的。
因此,讓我改你的程序:
:- use_module(library(clpfd)).
list_sum([], 0).
list_sum([E|Es], S) :-
S #= E+T,
list_sum(Es, T).
它首先將檢查的第一個條件list_sum([],0)。當條件不滿足時,會將列表分成H和T兩部分呢?
你的問題意味着有一個控制流(「雖然是這樣的典型構造暗示它」)。但它也可能以不同的方式工作。考慮查詢:
?- list_sum(Xs,0).
Xs = [] ;
Xs = [0] ;
Xs = [_G1710, _G1713],
_G1710+_G1713#=0 ...
下面我們請什麼列出存在,其總和爲0。現在你的「同時」不再有意義。
我們得到的答案是:空白列表;與0
的列表;一個兩元素列表,其中元素的總和爲0;等等......
瞭解這種方案的最佳方式是閱讀他們作爲像這樣的關係:
list_sum([], 0
:空列表具有總和0。
的規則現在讀最好的箭頭:-
即,從右到左的方向:
list_sum(Es, T).
:*提供Es
是總和T
列表,並...
S #= E+T
:... S
是E
加T
...
:-
...那麼我們可以得出結論...
list_sum([E|Es], S)
:S
是列表[E|Es]
的總和。
以這種方式可以理解這些事情,而不必提及過程細節。還有更多的理解終止請參閱failure-slice。
非常感謝。非常感謝你 。上帝祝福你 。我很難理解這一點。但你對我所做的一切都很簡單 – user3018890
好的解釋,但「用102返回」等等,有點讓人誤解,特別是對於曾經在程序上思考的人。 Prolog子句不返回值;他們根本不「返回」。比如說「成功地用X綁定到102」等等會更準確。 –
@TedHopp我也想過這個 - 返回有點誤導。我添加了「with」,試圖暗示價值不是從程序意義上「返回」的。不過,我喜歡你的措辭比我的更好 - 感謝你的評論! – dasblinkenlight