2016-10-27 72 views
1

我正在編寫一個Prolog謂詞,將前三個元素從編號列表中刪除並打印結果。編號列表的例子:簡單的Prolog程序:「參數沒有充分實例化」錯誤

[e(f,1),e(o,2),e(o,3),e(b,4),e(a,5),e(r,6)]. 

原來斷言對於正常的名單看起來是這樣的:

strim([H|T],R) :- 
    append(P,R,[H|T]), 
    length(P,3). 

所以,既然長度斷言完全適用於編號列表,以及,我只有寫謂詞該追加一個編號列表到另一個:

compose([],L,[L]). 
compose([e(F,C)|T],e(A,_),[e(F,C)|L]) :- 
    N is C+1, 
    compose(T,e(A,N),L). 

napp(X,[],X). 
napp(L,[e(X,Y)|T],M):- 
    compose(L,e(X,Y),L1), 
    napp(L1,T,M). 

我預期的編號列表謂語是謂語正常名單稍加修改的版本,所以我寫了這個:

numstrim([e(X,Y)|T],R) :- 
    napp(P,R,[e(X,Y)|T]), 
    length(P,3). 

不過,我得到這個錯誤:

ERROR: compose/3: Arguments are not sufficiently instantiated 

可能有人請解釋什麼引起的錯誤,以及如何避免呢?我是Prolog的新手。

+0

'N是C + 1'要求'C'被實例化,因爲它試圖評估'C + 1'。 – lurker

+0

@lurker好吧!對不起,要問這樣一個簡單的問題,但它會如何看待我的代碼?我讀了一些關於實例化變量的內容,但是我沒有看到在這種情況下我能做什麼...... – COLOuRSLIDES

+0

一個簡單的問題沒有錯。 :)但你最終可能會做更多的功課。 「實例化」意味着它需要一個綁定它的值。所以如果'C'沒有值,那麼Prolog就不能評估'C + 1',並且你會得到一個實例化錯誤。爲了解決它,你需要檢查你的邏輯並確保'C'有一個值。你叫'compose(L,e(X,Y),L1)',Prolog最終會嘗試'compose/3'的第二個子句,它與'[e(F,C)| T]沒有與'C'綁定的值。所以'N是C + 1'因爲實例化錯誤而失敗。 – lurker

回答

2

實例化的錯誤都在使用moded謂詞的Prolog程序的一個普遍現象:這些都是隻有在特殊情況下使用謂詞,要求例如,一些參數是完全實例

作爲初學者,我認爲你應該使用更一般的謂詞來代替,這樣你就可以自由地交換目標的順序,而且不必考慮程序上的限制,至少不會那麼早,也沒有自由實驗你的代碼的能力。

例如,在你的情況下,以下瑣碎變化compose/3讓你在所有方向上工作的斷言:

 
compose([], L, [L]). 
compose([e(F,C)|T], e(A,_), [e(F,C)|L]) :- 
     N #= C+1, 
     compose(T, e(A,N), L). 

在這裏,我只是取代了moded謂詞(is)/2CLP(FD)約束(#=)/2,其中completeley包含更多的低級謂詞整數。

這個小變化後(取決於您的Prolog的系統上,您可能需要導入庫使用更通用算術謂詞),我們得到:

 
?- numstrim([e(f,1),e(o,2),e(o,3),e(b,4),e(a,5),e(r,6)], Es). 
nontermination 

於是,我們發現,實例化錯誤實際上已經掩蓋了一個不同的問題,這個問題只能在程序上被理解,而且現在已經被揭示出來。

爲了改善這一點,我現在轉身的numstrim/2的兩個目標:

 
numstrim([e(X,Y)|T], R) :- 
     length(P, 3), 
     napp(P, R, [e(X,Y)|T]). 

這是因爲length(P, 3)總是終止,並且將始終終止第一最多可提高目標永遠不會惡化純粹的單調邏輯程序的終止屬性。

所以現在我們得到:

 
?- numstrim([e(f,1),e(o,2),e(o,3),e(b,4),e(a,5),e(r,6)], Es). 
Es = [e(b, _1442), e(a, _2678), e(r, _4286)] . 

也就是說,至少我們得到答案吧!

然而,謂語仍不會終止普遍,因爲我們得到:

 
?- numstrim([e(f,1),e(o,2),e(o,3),e(b,4),e(a,5),e(r,6)], Es), false. 
nontermination 

我離開這個固定作爲練習。