3

私の最後の試験ではdouble/2、次の指示に従って、 と呼ばれる Prolog 述語を作成するdouble(X, Y)必要がありYましXX。たとえば、クエリの double([1, 3, 2, 4], X). 結果は X = [1, 3, 4, 8].

functoreven/1を定義せずに簡単に使用できるようにしました (実際、定義するのは非常に簡単です)。これは、引数が偶数の場合は true であり、そうでない場合は false です。私は実際に functor も使用してプログラムを作成することになりましたodd/1。しかし、教授は私にこう言いました。では、どうしてこのように書けるようになったのだろうか。

私が書いたものは次のとおりです。

double([], []).
double([N|L], [N|D]) :- odd(N), !, double(L, D).
double([N|L], [M|D]) :- even(N), M is 2*N, double(L, D).

even(N)注意:コードの最後の行から削除しても (つまり、 only を使用する場合odd(N)、これは only を使用するのと実質的に同じです。これは、even(N)そのうちの 1 つしか使用しないためです)、プログラムは引き続き機能します。しかし、これは望ましい解決策ではありません。なぜなら、この方法では「カット」が赤いカットになるからです (私のプログラムでは緑のカットです)。

4

2 に答える 2

4

代わりに、標準のif-then-else制御構造を使用できます。

double([], []).
double([N|L], [M|D]) :-
    (   even(N) ->
        M is 2*N
    ;   M is N
    ),
    double(L, D).

この代替ソリューションのパフォーマンス上の利点 (整数が奇数でない場合に計算の繰り返しを回避することを除く) は、Prolog システムが最初の引数のインデックス付けを実装していると仮定すると (ほとんどの場合)、double/2述語の正しい節が呼び出しごとに常に選択されることです。選択ポイントを作成せずに (述語がインスタンス化された最初の引数で呼び出されると仮定しますが、これまたはあなたの定義定義はそうでなければ機能しません)。最初の句では、最初の引数はアトム (空のリスト) であるのに対し、2 番目の句では引数は (空でない) リストであることに注意してください。最初の引数のインデックス付けは、現在の目標を解決するために使用できない証明中に句を試行することを避けるために使用されます。

于 2014-11-14T21:09:46.553 に答える