私はPrologを紹介されたばかりで、整数のリストの最大値を見つける述語を書き込もうとしています。最初から比較するものと、最後から比較するものを書く必要があります。これまでのところ、私は持っています:
max2([],R).
max2([X|Xs], R):- X > R, max2(Xs, X).
max2([X|Xs], R):- X <= R, max2(Xs, R).
Rはまだ開始されていないので、比較することはできません。これを完了するには3つの引数が必要ですか?
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.
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.
最初または最後から開始することに関する宿題の制約を無視すると、数値の最大値を取得する述語を実装する適切な方法は次のとおりです。
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)).
ラムダ式 および メタ述語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/2
とfdvars_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([A、B、C]、M)。 %より一般的な使用法 エラー:is/2:引数が十分にインスタンス化されていません ?-fdvars_max([A、B、C]、M)。 M#> = _ X、M#> =C、M#= max(C、_X)、_ X#> =A、_X#> =B、_X#= max(B、A)。 %残存目標
非常に単純なアプローチ(最初から開始)は次のとおりです。
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.
あなたが言ったように、算術式を評価したい場合は、変数をインスタンス化する必要があります。これを解決するには、最初に再帰呼び出しを行い、次に比較する必要があります。
それが役に立てば幸い!
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
Prologのリストの最大数?
max([],A):-print(A),!.
max([Head | Tail] , A):-A =< Head ,A1 is Head , max(Tail,A1) ; max(Tail,A).
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).