2016-07-20 43 views
5

我開始學習Prolog,我想要一個給定整數P的程序給整數AB,使得P = A² + B²。如果沒有滿足這個方程的AB值,false應退還Prolog程序獲取(整數)數字作爲兩個整數正方形的總和,爲什麼它不起作用?

例如:如果P = 5,它應該給A = 1B = 2(或A = 2B = 1),因爲1² + 2² = 5

我想這應該工作:

giveSum(P, A, B) :- integer(A), integer(B), integer(P), P is A*A + B*B. 

與查詢:

giveSum(5, A, B). 

然而,事實並非如此。我該怎麼辦?我對Prolog很陌生,所以我仍然犯了很多錯誤。

在此先感謝!

回答

6

integer/1是一個非單調謂詞。它是而不是這種關係允許您在這種情況下應用的推理。爲了舉例說明這一點:

 
?- integer(I). 
false. 

不存在整數,是嗎? 顏色我很驚訝,至少可以說!

而不是這種非關係結構,使用您的Prolog系統的CLP(FD)約束推理整數。

例如:

 
?- 5 #= A*A + B*B. 
A in -2..-1\/1..2, 
A^2#=_G1025, 
_G1025 in 1..4, 
_G1025+_G1052#=5, 
_G1052 in 1..4, 
B^2#=_G406, 
B in -2..-1\/1..2 

而對於具體的解決方案:

 
?- 5 #= A*A + B*B, label([A,B]). 
A = -2, 
B = -1 ; 
A = -2, 
B = 1 ; 
A = -1, 
B = -2 ; 
etc. 

CLP(FD)的約束是可以在你所期望的方式來使用完全純淨的關係。有關更多信息,請參閱

其他的事情,我注意到:

  • use_underscores_for_readability_as_is_the_convention_in_prolog代替ofMixingTheCasesToMakePredicatesHardToRead
  • 使用聲明性名稱,避免勢在必行。例如,爲什麼叫它give_sum?如果總和已經給出,這個謂詞也是非常有意義的。那麼,例如sum_of_squares/3呢?
+0

非常感謝您的回覆。 我有幾個問題。如果你能回答他們,那將是非常棒的。 '非單調謂詞'是什麼意思,/ 1或/ 3是什麼意思,以及label()函數做了什麼? 在因特網上,我讀了「爲Vars中的每個變量賦值」,標籤意味着系統地嘗試使用有限域變量Vars的值,直到所有變量都被研磨爲止。爲函數標籤(),但我不是很明白它。 也感謝您注意到不好的做法,我更改了名稱,將來會使用下劃線和聲明式名稱。 – Kevin

+1

請爲此單獨提出問題。他們都值得自己討論:1)單調性的定義和2)什麼是「標籤」?只有一個問題很簡單,可以在評論中回答:'f/3'是一個**謂詞指示符**,表示一個名爲'f'的謂詞,帶有3 *個參數*。請注意,我們總是討論**謂詞**,它們比*函數*更普遍。偉大的名字!查找和使用對謂詞**一般性**公平的好的陳述性名稱是在Prolog中編程時非常重要的一個方面,也可能是其中較難的一個。 – mat

1

出於效率考慮,Prolog的實施者已經選擇了很多年前的許多妥協方案。現在,您的Prolog有可能實現高級整數運算,就像CLP(FD)一樣。如果是這樣的話,mat答案是完美的。但是一些序言(可能是一個天真的ISO Prolog兼容處理器)可能會抱怨缺少標籤/ 1和(#=)/ 2。所以,傳統的Prolog的溶液:該技術被稱爲生成和測試

giveSum(P, A, B) :- 
    (integer(P) -> between(1,P,A), between(1,P,B) ; integer(A),integer(B)), 
    P is A*A + B*B. 

之間/ 3它不是一個ISO內置,但它而不是更容易(#=)/ 2和標籤/ 1至寫:)

無論如何,請遵循墊'的建議,並避免'命令'的命名。通常對關係的描述更好,因爲Prolog就是這樣的:關係語言。

+2

我通常不會downvoting,但... – repeat

相關問題