その情報を取得する方法は他にもあります。
most_wins(Id) :-
wins(Id, W), \+ (wins(_, W1), W1 > W).
または、Prolog に library( aggregate ) がある場合:-
most_wins(Id) :-
aggregate(max(W, Id), wins(Id, W), max(_, Id)).
またはsetof /3を使用できます
most_wins(Id) :-
setof(N-Id, W^(wins(Id, W), N is -W), [_-Id|_]).
明らかに速度とメモリのトレードオフがあります。最初の方法はメモリ効率が良い O(1) ですが、候補のセットを 2 回スキャンするため、時間の複雑さは O(N^2) になります。2番目と3番目は(私が思うに)実質的に同等です.SWI-prologの現在の実装では、両方とも候補のリストを作成し(その後、空間でO(N)になります)、要素を選択します-時間でO(N log N)。
候補が事実である場合は、最初のものを使用してください。
editさらに別の方法として、効率の観点からは、バックトラック不可能な代入を利用します。外出先で最大を維持しながら、候補をスキャンするだけです。Plain Prolog では、そのようなタスクを実行するために assert/retract が必要になるため、かなり非効率になります。しかし、多くのプロローグには、「グローバル」変数を保存するためのより効率的な方法があります...