2012-12-03 20 views
2

的查詢sum(X,Y)會回答X的所有正約數的總和(不包括X本身) 說,sum(12,Y)會回答Y=16因爲1,2,3,4,6是12求和所有正除數

的除數

我打算實施下面的prolog程序,但它失敗了,說一些變量沒有實例化。

sum(X,Y) :- f(X,Y,1). 
f(X,Y,F) :- X>Y,X>F, 0 is X mod F, F1 is F+1, f(X,Y1,F1), Y is F+Y1. 
f(X,Y,F) :- X>Y,X>F, not(0 is X mod F), F1 is F+1, f(X,Y,F1). 

上述程序有什麼問題?

感謝您的幫助!

+2

我認爲你需要使用[clpfd](http://www.swi-prolog.org/man/clpfd。html)而不是原始算術,因爲在給出這些限制的情況下,Prolog不夠聰明以至於猜測範圍內的數字。 –

回答

2

我不會告訴你如何編寫sum_of_divisors函數,因爲它不會很有教育意義。相反,我可以試着告訴你如何理解你的sum(12,Y)查詢出了什麼問題。

讓我們來看看錯誤:

?- sum(12, Y). 
ERROR: >/2: Arguments are not sufficiently instantiated 
    Exception: (8) f(12, _G215, 1) ? a 
% Execution Aborted 

後您查詢

?- sum(12, Y). 

序言引擎讀取sum(X,Y) :- f(X,Y,1).,因此它計算第二斷言:

f(X,Y,F) 

其中X = 12F = 1並且Y未被綁定。所以它試圖這樣:

:- X>Y 

這是

12 > _G350 

其中_G350Y,一個不實例變量。

的問題是,算術謂詞像(>)/2(和喜歡(+)/2(*)/2,等..)要求您要比較實例化這兩個變量。您無法查詢是這樣的:

?- 12 > X 

,並期望序言引擎查找到所有綁定X這樣X小於12所以,你需要重新考慮你的解決問題的方法,並記住你只能用NUMBERS進行算術運算,而不能用數字和變量進行運算。

2

對於完整聲明式算術,您可以按照已經建議的方式使用CLP(FD)。例如,在SWI-Prolog中,當我簡單地用(#=)/ 2等替換(是)/ 2以推廣基本算術運算,以便它們也可以在兩側上使用變量時,我得到:

:- use_module(library(clpfd)). 

sum(X,Y) :- f(X,Y,1). 

f(X,Y,F) :- X#>Y,X#>F, 0 #= X mod F, F1 #= F+1, f(X,Y1,F1), Y #= F+Y1. 
f(X,Y,F) :- X#>Y,X#>F, 0 #\= X mod F, F1 #= F+1, f(X,Y,F1). 

現在你的樣品查詢產生:

?- sum(12, Y). 
false. 

所以很明顯的程序過於具體,檢查你是否忘記描述一個重要案例。

相關問題