web-dev-qa-db-ja.com

リストで最大値を見つける-Prolog

私はPrologを紹介されたばかりで、整数のリストの最大値を見つける述語を書き込もうとしています。最初から比較するものと、最後から比較するものを書く必要があります。これまでのところ、私は持っています:

max2([],R).
max2([X|Xs], R):- X > R, max2(Xs, X).
max2([X|Xs], R):- X <= R, max2(Xs, R).

Rはまだ開始されていないので、比較することはできません。これを完了するには3つの引数が必要ですか?

5
user2796815
my_max([], R, R). %end
my_max([X|Xs], WK, R):- X >  WK, my_max(Xs, X, R). %WK is Carry about
my_max([X|Xs], WK, R):- X =< WK, my_max(Xs, WK, R).
my_max([X|Xs], R):- my_max(Xs, X, R). %start

他の方法

%max of list
max_l([X],X) :- !, true.
%max_l([X],X). %unuse cut
%max_l([X],X):- false.
max_l([X|Xs], M):- max_l(Xs, M), M >= X.
max_l([X|Xs], X):- max_l(Xs, M), X >  M.
5
BLUEPIXY

BLUEPIXYの回答の代わりに、SWI-Prologには組み込みの述語 max_list/2 、それはあなたのための検索を行います。また、より遅い方法を検討することもできます。IMOは、より多くの組み込み関数と非決定性(およびバックトラック)に精通するのに役立ちます。

slow_max(L, Max) :-
   select(Max, L, Rest), \+ (member(E, Rest), E > Max).

収量

2 ?- slow_max([1,2,3,4,5,6,10,7,8],X).
X = 10 ;
false.

3 ?- slow_max([1,2,10,3,4,5,6,10,7,8],X).
X = 10 ;
X = 10 ;
false.

編集

3つの引数を厳密に必要としないのではなく、比較を実行するために変数を適切にインスタンス化する必要があることに注意してください。次に、値の流れを「逆」にすることができます。

max2([R], R).
max2([X|Xs], R):- max2(Xs, T), (X > T -> R = X ; R = T).

繰り返しますが、これは他の回答で提案されている3つの引数ループよりも遅くなります。これは、「末尾再帰の最適化」が無効になるためです。また、最大値のoneを見つけるだけです:

2 ?- max2([1,2,3,10,5,10,6],X).
X = 10 ;
false.
4
CapelliC

最初または最後から開始することに関する宿題の制約を無視すると、数値の最大値を取得する述語を実装する適切な方法は次のとおりです。

list_max([P|T], O) :- list_max(T, P, O).

list_max([], P, P).
list_max([H|T], P, O) :-
    (    H > P
    ->   list_max(T, H, O)
    ;    list_max(T, P, O)).
4
salva

ラムダ式 および メタ述語foldl/4 、およびオプションで clpfd を使用してこれを行う方法は次のとおりです。 =:

:- use_module([library(lambda),library(apply),library(clpfd)]).

numbers_max([Z|Zs],Max) :- foldl(\X^S^M^(M is max(X,S)),Zs,Z,Max).
fdvars_max( [Z|Zs],Max) :- foldl(\X^S^M^(M #= max(X,S)),Zs,Z,Max).

いくつかのクエリを実行しましょう!

?-numbers_max([1、4、2,3]、M)。 %整数:すべてが異なる
 M = 4。 %は決定論的に成功します
?-fdvars_max([1、4、2,3]、M)。
 M = 4。 %は決定論的に成功します
 
?-numbers_max([1、4、2、3、4]、M)。 %整数:Mは2回発生します
 M = 4。 %は決定論的に成功します
?-fdvars_max([1、4、2、3、4]、M)。
 M = 4。 %は決定論的に成功します

リストが空の場合はどうなりますか?

?- numbers_max([],M).
false.
?- fdvars_max( [],M).
false.

最後に、numbers_max/2fdvars_max/2の違いを示すいくつかのクエリ:

?-numbers_max([1,2,3、10.0]、M)。 %ints + float 
 M = 10.0。
?-fdvars_max([1,2,3、10.0]、M)。 %ints + float 
エラー:ドメインエラー: `clpfd_expression 'が必要です、` 10.0' 
 
?-numbers_max([ABC]、M)。 %より一般的な使用法
エラー:is/2:引数が十分にインスタンス化されていません
?-fdvars_max([ABC]、M)。
 M#> = _ X、M#> =C、M#= max(C、_X)、_ X#> =A、_X#> =B、_X#= max(BA)。 %残存目標
3
repeat

非常に単純なアプローチ(最初から開始)は次のとおりです。

maxlist([],0).

maxlist([Head|Tail],Max) :-
    maxlist(Tail,TailMax),
    Head > TailMax,
    Max is Head.

maxlist([Head|Tail],Max) :-
    maxlist(Tail,TailMax),
    Head =< TailMax,
    Max is TailMax.

あなたが言ったように、算術式を評価したい場合は、変数をインスタンス化する必要があります。これを解決するには、最初に再帰呼び出しを行い、次に比較する必要があります。

それが役に立てば幸い!

2
toioski
list_max([L|Ls], Max) :- foldl(num_num_max, Ls, L, Max).

num_num_max(X, Y, Max) :- Max is max(X, Y).

%Query will be

?-list_max([4,12,5,3,8,90,10,11],Max).
Max=90
1
Tanusree Roy

Prologのリストの最大数?

max([],A):-print(A),!.

max([Head | Tail] , A):-A =< Head ,A1 is Head , max(Tail,A1) ; max(Tail,A).
0
jane
 maximum_no([],Max):-

    write("Maximum No From the List is:: ",Max).
maximum_no([H|T],Max):-
    H>Max,
    N = H,
    maximum_no(T,N).
maximum_no(L,Max):-
    maximum_no(L,Max).
0
Harsh Mehta