剛開始使用prolog編程時,我遇到了一些問題。我所擁有的函數應該取值爲X並將其複製N次。我的函數返回N個內存位置的列表。這是代碼,任何想法?prolog函數返回內存位置而不是值
duple(N,_,M):- length(M,Q), N is Q.
duple(N,X,M):- append(X,M,Q), duple(N,X,Q).
剛開始使用prolog編程時,我遇到了一些問題。我所擁有的函數應該取值爲X並將其複製N次。我的函數返回N個內存位置的列表。這是代碼,任何想法?prolog函數返回內存位置而不是值
duple(N,_,M):- length(M,Q), N is Q.
duple(N,X,M):- append(X,M,Q), duple(N,X,Q).
這些都不是內存不會忽略。那些是自由變量。你所看到的是他們在你選擇的序言系統中的內部名字。然後,正如@chac指出的(+1順便說一句),第三個條款是沒有意義的!也許你可以試着告訴我們你的意思,這樣我們就可以明白如何正確地做到這一點。
我要去給你謂詞的兩種實現方式,試圖告訴你正確的Prolog的語法:
duple1(N, X, L) :-
length(L, N),
maplist(=(X), L).
在這裏,您duple1/3
謂詞,我們告訴序言中所產生的名單L
的長度是N
,然後我們告訴它,L
的每個元素應該與X
統一,以使謂詞成立。
另一個這樣做將通過遞歸構建結果列表「手動」:
duple2(0, _X, []).
duple2(N, X, [X|L]) :-
N > 0,
NewN is N - 1,
duple1(NewN, X, L).
不過,請注意,因爲我們使用>/2
,is
和-/2
,即算術,我們防止序言使用此謂詞有幾種方式,如:
?- duple1(X, Y, [xyz, xyz]).
X = 2,
Y = xyz.
這個以前工作過,在我們的第一個謂詞中!
希望這有一些幫助。
我想你打電話給你的謂詞,例如,以這樣的方式
?- duple(3,xyz,L).
,你會得到
L = [_G289, _G292, _G295] ;
ERROR: Out of global stack
如果您嘗試
?- length(X,Y).
X = [],
Y = 0 ;
X = [_G299],
Y = 1 ;
X = [_G299, _G302],
Y = 2 ;
X = [_G299, _G302, _G305],
Y = 3 ;
X = [_G299, _G302, _G305, _G308],
Y = 4 .
...
你可以看到發生了什麼:
你的查詢將匹配指定的*M*
,顯示M個未被證實的變量列表(內存位置),然後繼續回溯並生成更長的列表,直到有堆棧空間。你的第二條規則永遠不會開火(我不明白它的目的)。
發電機是更容易這樣寫:
duple(N,X,M) :- findall(X,between(1,N,_),M).
測試:
?- duple(3,xyz,L).
L = [xyz, xyz, xyz].
感謝幫助了很多,我還不擅長與prolog合作。 – Dommol 2012-03-28 19:53:40
長度+ maplist是要走的路... – CapelliC 2012-03-28 20:18:55