1

これら 2 つのプログラムがありますが、正常に動作していません。最初の without_doubles_2(Xs, Ys) は、Ys が Xs に現れる要素の重複なしのリストである場合に真であることを示すはずです。Y の要素は X の逆順で、最初の重複値が保持されます。without_doubles_2([1,2,3,4,5,6,4,4],X) などは X=[6,5,4,3,2,1] を出力しますが、false を出力します。

without_doubles_2([],[]).
without_doubles_2([H|T],[H|Y]):- member(H,T),!,
                                 delete(H,T,T1),
                                 without_doubles_2(T1,Y).

without_doubles_2([H|T],[H|Y]):-    without_doubles_2(T,Y).

reverse([],[]).
reverse([H|T],Y):- reverse(T,T1), addtoend(H,T1,Y).

addtoend(H,[],[H]).
addtoend(X,[H|T],[H|T1]):-addtoend(X,T,T1).


without_doubles_21(X,Z):-  without_doubles_2(X,Y),
                           reverse(Y,Z).

2 つ目は、このプログラムに文字列を使用させる方法です。文字列から母音を削除し、子音のみを出力することになっています。

deleteV([H|T],R):-member(H,[a,e,i,o,u]),deleteV(T,R),!.
deleteV([H|T],[H|R]):-deleteV(T,R),!.
deleteV([],[]).
4

2 に答える 2

2

delete引数の順序が間違っているため、呼び出しは常に失敗します。

delete(+List1, @Elem, -List2)

だから代わりに

delete(H, T, T1)

あなたがしたい

delete(T, H, T1)

swi-prolog インタープリターのトレース機能を使用すると、このようなエラーを簡単に見つけることができtrace.ます。入力してトレース モードを開始し、述語を入力して、インタープリターが何をしているかを確認するだけです。この場合、失敗はdeleteステートメントに起因することがわかります。トレースに関連するドキュメントは、ここにあります

また、メンバー チェックと 3 番目の句を省略して述語を書き直すことができることにも注意してください。これは、delete([1,2,3],9001,[1,2,3])が true と評価されるためです。要素がリストにない場合、結果は入力と同じになります。したがって、述語は次のようになります (怠惰のために名前が短縮されています)。

nodubs([], []).
nodubs([H|T], [H|Y]) :- delete(T, H, T1), nodubs(T1, Y).

string_to_list2 番目の質問では、述語を使用して文字列を文字のリスト (ASCII コードとして表される) に変換できます。

文字列から母音を削除する述語については、次のように実装します (この問題に対するより良い解決策や、使用できるビルトインがいくつかありますが、私のプロローグはやや錆びています):

%deleteall(+L, +Elems, -R)
%a helper predicate for deleting all items in Elems from L
deleteall(L, [], L).
deleteall(L, [H|T], R) :- delete(L, H, L1), deleteall(L1, T, R).

deleteV(S, R) :-
    string_to_list(S, L),         %create list L from input string
    string_to_list("aeiou", A),   %create a list of all vovels
    deleteall(L, A, RL),          %use deleteall to delete all vovels from L
    string_to_list(R, RL).        %turn the result back into a string
于 2012-12-17T12:48:56.767 に答える
0

deleteV/2 は library( lists ) を利用できます:

?- subtract("carlo","aeiou",L), format('~s',[L]).
crl
L = [99, 114, 108].

重複を削除するには、並べ替え/2 を利用して/3を選択します。

nodup(L, N) :-
    sort(L, S),
    nodup(L, S, N).

nodup([], _S, []).
nodup([X|Xs], S, N) :-
    ( select(X, S, R) -> N = [X|Ys] ; N = Ys, R = S ),
    nodup(Xs, R, Ys).

テスト:

?- nodup([1,2,3,4,4,4,5,2,7],L).
L = [1, 2, 3, 4, 5, 7].

ssBarBee より、はるかに優れた編集

?- setof(X,member(X,[1,2,2,5,3,2]),L).
L = [1, 2, 3, 5].
于 2012-12-17T13:22:27.000 に答える