1

Prolog でリストを繰り返し処理して最大値を見つける方法は知っていますが、それぞれが個別の節である場合はどうなるでしょうか? たとえば、猫とその年齢がたくさんある場合、どのようにして最年長の子猫を見つけますか?

cat(sassy, 5).
cat(misty, 3).
cat(princess, 2).

私が最初に思ったのは、「うーん、最年長の猫は年長者がいない猫だ」ということでした。しかし、プロローグにうまく翻訳できませんでした。

oldest(X) :- cat(X, AgeX), cat(Y, AgeY), X \= Y, \+ AgeX < AgeY, print(Y).

これはまだ誤って「misty」と一致します。これを行う適切な方法は何ですか?最大を選択するために、より直接的に年齢を反復する方法はありますか?

4

5 に答える 5

4

猫で、それより年上の猫がいない場合、その猫は最年長です。それをプロローグに書きましょう:

oldest(X):- cat(X, _), not( thereAreOlders(X)), !.
thereAreOlders(X):- cat(X, N), cat(C, M), C\=X, M > N.

相談する場合:

?- oldest(X).
X = sassy.
于 2009-11-10T02:12:35.157 に答える
1

これは、すべてのソリューションをループし、常に前のベストよりも優れたソリューションを記録するソリューションです。最終的に、最適なソリューションが返されます。

記録は を使用して行われassert/1ます。Prolog が提供する場合 (SWI-Prolog が提供する場合)、バックトラック不可能なグローバル変数を使用することもできます。

このアプローチの利点は、各ソリューションを 1 回だけ考慮すること、つまり複雑さ O(n) であることです。したがって、starblue のソリューションよりも見栄えは悪いですが、より適切に動作するはずです。

% Data
cat(sassy, 5).
cat(misty, 3).
cat(miisu, 10).
cat(princess, 2).

% Interface
oldest_cat(Name) :-
    loop_through_cats,
    fetch_oldest_cat(Name).

loop_through_cats :-
    cat(Name, Age),
    record_cat_age(Name, Age),
    fail ; true.


:- dynamic current_oldest_cat/2.

record_cat_age(Name, Age) :-
    current_oldest_cat(_, CAge),
    !,
    Age > CAge,
    retract(current_oldest_cat(_, _)),
    assert(current_oldest_cat(Name, Age)).

record_cat_age(Name, Age) :-
    assert(current_oldest_cat(Name, Age)).


fetch_oldest_cat(Name) :-
    retract(current_oldest_cat(Name, _Age)).

使用例:

?- oldest_cat(Name).

Name = miisu

ミースは典型的なエストニアの猫の名前です。;)

于 2009-11-10T09:30:55.790 に答える
0

文体上の点では、ここにはいくつかの異なるアプローチがあります (非常にエレガントなものもあれば、より「読みやすい」ものもあります)。あなたが初心者なら、自分の好きなやり方を選んでください。しかし非効率的です。

後で効率化のためのテクニックを学ぶことができます。Prolog をお楽しみください。美しい言語です。

于 2013-03-26T17:14:28.130 に答える
-2

Prolog についてはあまり覚えていませんが、命令型プログラミング言語の場合のように問題を解決することを考えるべきではないことは知っています。

于 2009-11-09T21:31:00.600 に答える