2014-02-17 31 views
1

我是新來的Prolog,當我查詢 sortedUnion([1,1,1,2,3,4,4,5], [0,1,3,3,6,7], [0,1,2,3,4,5,6,7]). 我得到一個錯誤SWI序言 - 錯誤的論點不夠實例化

Exception: (7) unite([_G114, _G162, _G201, _G231, _G243], [_G249, _G297, _G336, _G357, _G369], [0, 1, 2, 3, 4, 5, 6, 7]) ? 

所以我希望有人能告訴我在哪裏,我的代碼是錯誤的爲什麼它是錯的?

%undup(L, U) holds precisely when U can be obtained from L by eliminating repeating occurrences of the same element     
undup([], []). 
undup([X|Xs], [_|B]) :- remove(X,Xs,K), undup(K, B). 

remove(_,[],[]). 
remove(Y,[Y|T],D) :- remove(Y,T,D). 
remove(Y,[S|T],[S|R]) :- not(Y = S), remove(Y,T,R). 

%sortedUnion(L1,L2,U) holds when U contains exactly one instance of each element 
%of L1 and L2 

sortedunion([H|T], [S|R], [F|B]) :- undup([H|T], N), undup([S|R], M), unite(N,M,[F|B]). 
unite([], [], []). 
unite([X], [], [X]). 
unite([], [X], [X]). 
unite([H|T], [S|R], [X|Xs]) :- S=H, X is S, unite(T, R, Xs). 
unite([H|T], [S|R], [X|Xs]) :- H<S, X is H, unite(T, [S|R], Xs). 
unite([H|T], [S|R], [X|Xs]) :- S<H, X is S, unite([H|T], R, Xs). 

回答

0

建議第一:儘量讓您的代碼儘可能簡單。您的代碼可以減少這種(即肯定的作品)

sortedunion(A, B, S) :- 
    append(A, B, C), 
    sort(C, S). 

但當然是有益的嘗試自行解決。無論如何,儘量避免無用的併發症。

sortedunion(A, B, S) :- 
undup(A, N), 
undup(B, M), 
unite(N, M, S). 

它相當於您的代碼,只是更簡單,因爲A = [H|T]等等。

然後測試undup/2:

1 ?- undup([1,1,1,2,3,4,4,5],L). 
L = [_G2760, _G2808, _G2847, _G2877, _G2889] ; 
false. 

顯然,並不是你所期望的。罪魁禍首應該是那個變種。確實,這個作品:

undup([], []). 
undup([X|Xs], [X|B]) :- remove(X,Xs,K), undup(K, B). 

2 ?- undup([1,1,1,2,3,4,4,5],L). 
L = [1, 2, 3, 4, 5] ; 
false. 

現在,團結/ 3。首先,是/ 2被濫用。它介紹算術,然後在這裏簡單的統一就足夠了:X = S

然後將基準的情況下被硬編碼到地方工作列表長度由1不同,最多再有,簡單的代碼應工作得更好:

unite([], [], []). 
unite(X, [], X). 
unite([], X, X). 
... 

此外,請注意第一條是沒用的,已經被所涵蓋(都)第二和第三條款。

+0

有一個作業指導不使用任何預定義的謂詞,我們沒有在課堂上去。我現在意識到,當我不應該使用'_'時,這是多麼明顯。 – redLightening