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]). 出现错误

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).
4

1 回答 1

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.

显然,不是你所期望的。罪魁祸首应该是anon var。确实,这有效:

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。首先,is/2 被滥用。它介绍了算术,然后在这里简单的统一就足够了:X = S.

然后,基本情况被硬编码以在列表长度最多相差 1 的情况下工作。同样,更简单的代码应该更好地工作:

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

另外,请注意第一个子句是无用的,已经被(两个)第二个和第三个子句覆盖。

于 2014-02-18T00:22:30.977 回答