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

また、最初の節は役に立たないことに注意してください。既に (両方の) 2 番目と 3 番目の節でカバーされています。

于 2014-02-18T00:22:30.977 に答える