私は Prolog を紹介されたばかりで、整数のリストの最大値を見つける述語を書こうとしています。最初から比較するものと、最後から比較するものを書く必要があります。これまでのところ、私は持っています:
max2([],R).
max2([X|Xs], R):- X > R, max2(Xs, X).
max2([X|Xs], R):- X <= R, max2(Xs, R).
R はまだ開始されていないため、比較することはできません。これを完了するには 3 つの引数が必要ですか?
私は Prolog を紹介されたばかりで、整数のリストの最大値を見つける述語を書こうとしています。最初から比較するものと、最後から比較するものを書く必要があります。これまでのところ、私は持っています:
max2([],R).
max2([X|Xs], R):- X > R, max2(Xs, X).
max2([X|Xs], R):- X <= R, max2(Xs, R).
R はまだ開始されていないため、比較することはできません。これを完了するには 3 つの引数が必要ですか?
最初または最後から開始することに関する宿題の制約を無視すると、数値の最大値を取得する述語を実装する適切な方法は次のとおりです。
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)).
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.
ラムダ式とmeta-predicate 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). % integers: 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.
あなたが言ったように、算術式を評価したい場合は、変数をインスタンス化する必要があります。これを解決するには、まず再帰呼び出しを行い、次に比較する必要があります。
それが役に立てば幸い!