3

私は特定の要素でプロローグを分割しようとしてきました。近づいてきましたが、リストの左側が表示されません。

split(X,[Y|L]) :- split(X,[Y|L],[Y|K],M).
split(_,[],[],[]).
split(X,[Y|L],K,[Y|M]) :- X < Y, split(X,L,K,M).
split(X,[Y|L],[Y|K],M) :- X >= Y, split(X,L,K,M).
split(X,[Y|L],[Y|K],M) :- X = Y, write(Y), write(' '), write(L).

入力:

split(2,[1,2,3,4,5]).

戻り値:

2 [3,4,5]

返して欲しい

[1,2] [3,4,5].
4

2 に答える 2

2

私はあなたがここで何をしたいのか完全にはわかりません。たとえば、何をsplit(5, [1,2,3,4,5])することになっていますか?さらに言えば、入力リストがソートされていると想定しても安全ですか?私はそう仮定するつもりです。

ルールの基本的な問題split/2は、outパラメーターがないことです。Prologは、ほとんどのプログラミング言語とは動作が異なります。のようなものはありませんreturn。最初はこれは壊滅的な制限のように感じますが、Prologでは実際に好きなだけ結果を「返す」ことができます。split/2このコードを見ると、outパラメータがないように見えるので、この理解のほぼ半分になっているように見えsplit/4ますが、必要なoutパラメータの両方を持っているものが呼び出されます。

手始めに、私はその考えを放棄して、仕事にsplit/2取り掛かろうとしsplit/4ました。あなたが持っているものはそこにあまり狂っているようには見えません:

?- split(2, [1,2,3,4,5], X, Y).
X = [1, 2],
Y = [3, 4, 5] .

?- split(5, [1,2,3,4,5], X, Y).
X = [1, 2, 3, 4, 5],
Y = [] .

?- split(1, [1,2,3,4,5], X, Y).
X = [1],
Y = [2, 3, 4, 5] .

これは、ほとんどのルールが正しいことを示しています。問題が発生するのは、追加のソリューションです。

?- split(2, [1,2,3,4,5], X, Y).
... ;
2 [3,4,5]
X = [1, 2|_G317] ;
false.

?- split(5, [1,2,3,4,5], X, Y).
... ;
5 []
X = [1, 2, 3, 4, 5|_G326] ;
false.

?- split(1, [1,2,3,4,5], X, Y).
... ;
1 [2,3,4,5]
X = [1|_G314].

そこに書かれていることから、これらの追加のソリューションが最後のルールX = Y, write(Y)...などによって生成されたことがわかります。そのルールを削除するだけで、で目的の動作が生成されますsplit/4

split/2先に進むと、おそらく実際に必要なものではなく、split/31つの出力パラメーターであるリストのリストを使用することだと思います。私たちがこれまでに持っているものに基づいて生成することはそれほど難しいことではありません:

split(X, List, [Before, After]) :- split(X, List, Before, After).

それを実行すると、あなたが言及した望ましい結果が得られることがわかります。

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

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

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

お役に立てれば!

于 2012-10-19T05:16:54.433 に答える
1

私はこのように書くので、他のユースケースが必要な場合は述語を「再利用」できます(ほとんどの場合、出力ストリームへの書き込みは必要なものではありません)

split(X, Xs) :-
    split(X, Xs, L, R), format('~w ~w', [L, R]).

split(_, [], [], []).
split(X, [Y|Xs], [], [Y|Xs]) :-
    X < Y.
split(X, [X|Xs], [X], Xs).
split(X, [Y|Xs], [Y|Ls], Rs) :-
    X > Y,
    split(X, Xs, Ls, Rs).

テスト

?- split(2,[1,2,3,4,5]).
[1,2] [3,4,5]
true ;
false.
于 2012-10-19T09:17:51.700 に答える