2

私はこれを試しました

 fun([],[]).
 fun([A|_],B) :- number(A), B is A +1,!.
 fun([H|T],R) :- fun(T,R).

私はそれが間違っていることを知っています、あなたは私を助けてくれますか? ありがとう

4

2 に答える 2

3

プログラムが機能しないことを確認するには、次のいずれかを試してください。

?- fun([1],L).
L = 2.

?- fun([1],[]).
true.

?- fun([X],L).
L = [].

したがって、これは明らかに非リレーショナルな動作を示しています。最初のクエリでは、 an を要求し、答えとしてLget を取得L = 2しますが、次に answer であることを尋ね[]ます。システムもそれを受け入れます。明らかに、定義を関係にすることはできません。犯人は確かにカットです。

それとは別に、問題を確認する方法は他にもあります。1 つのルールだけを検討するだけで十分です。最初のルール ( fun([A|_],B) :- number(A), B is A +1,!.) は、2 番目の引数が (特定の状況では) 整数でなければならないことを示しています。しかし、それはリストでなければなりません。2 番目の規則 ( fun([H|T],R) :- fun(T,R).) は、任意の要素をスキップできることを示しています。明らかに、それは意味のある定義の一部ではありません。

最も簡潔な方法は、 library(lambda)maplist/3で定義されている高次の述語とラムダ式を使用することです。このように書くと、中間述語は通常使用されません。

fun(Xs, Ys) :-
   maplist(\X^Y^(Y is X+1), Xs, Ys).

次のバージョンでは、ラムダを回避し、代わりに具体的な定義を使用します。

msucc(X, Y) :-
   Y is X+1.

fun(Xs, Ys) :-
   maplist(msucc, Xs, Ys).

succ/2実際、多くのプロローグに存在し、プロローグ プロローグ の一部である事前定義された述語があります。

fun(Xs, Ys) :-
   maplist(msucc, Xs, Ys).

それを定義する最も「歩行者」な方法は、述語定義を直接使用することです。

fun([], []).
fun([X|Xs], [Y|Ys]) :-
   Y is X+1,
   fun(Xs, Ys).

あなたはどちらを好みますか?

maplist-family の詳細:リスト要素に述語を適用するプロローグ マップ プロシージャ


Prolog を学びたい場合は、まず純粋な関係に固執してください。カットは避けてください。のような副作用を避けてくださいwrite。も避けてください(is)/2とそれ以降のを使用します。スタディの終了および非終了の-sliceおよび

于 2014-06-18T21:18:19.940 に答える
0

問題は、一貫性がなく、再帰が完了していないことです。

あなたのコードでは、次のようなことが当てはまります。

fun([a,b,c],X) .

X の値[]は になりますが、

fun([a,1,b],X) .

X の値は になります2

リストの最初の数字を見つけて 1 ずつ増やしたい場合は、次のようにします。

fun([X|Xs],Y) :- number(X) , ! , Y is X+1 .
fun([_|Xs],Y) :- fun(Xs,Y) .

リスト内の各数値を増やしたい場合は、次のようにしてみてください。

fun( []    , []      ) .  % if the source list is exhausted, we're done.
fun( [X|Xs] , [Y|Ys] ) :- % otherwise,
  number(X) ,             % - if X is a number,
  Y is A+1                % - we increment it to get Y
  fun( Xs , Ys ) .        % - and recurse down on the tails of the respective lists
fun( [X|Xs] , [X|Ys] ) :- % otherwise, add X to the result list
  \+ number(X) ,          % - assuming X is not a number,
  fun(Xs,Ys) .            % - and recurse down.

これがより簡潔に次のように述べられる可能性があることに注意してください。

fun( [] , [] ) :-
fun( [X|Xs] , [Y|Ys] ) :-
  increment(X,Y) ,
  fun( Xs , Ys )
  .

increment(X,Y) :- number(X) , ! , Y is X+1 .
increment(X,X) .

または、さらに簡潔に

fun( [] , [] ) .
fun( [X|Xs] , [Y|Ys] ) :-
  ( number(X) -> Y is X+1 ; Y = X ) ,
  fun(Xs,Ys).

A -> B ; C構文は含意演算子です。

于 2014-06-18T21:55:58.770 に答える