4

SWI Prologには、nth1というリストのn番目の項目を見つける述語があります。独自のバージョンの述語を実装したいのですが、listing(nth1)コードを見ると、SWIは非常に複雑です。それを行うためのより簡単な方法はありますか?

ありがとうございました :)。

4

3 に答える 3

4

一般的な(可逆的な)整数演算に有限領域制約を使用することを検討してください。

:- use_module(library(clpfd)).

nth1(1, [E|_], E).
nth1(N, [_|Xs], E) :-
        N #> 1,
        N #= N1 + 1,
        nth1(N1, Xs, E).
于 2010-11-21T14:50:10.210 に答える
2

述語を使用して変数インデックスから生成できるため、SWIコードは少し複雑です。

?- nth1(Idx,[a,b,c],X).
Idx = 1,
X = a ;
Idx = 2,
X = b ;
Idx = 3,
X = c ;
false.

その動作を望まない場合は、次nth1/3の点で簡単に実装できますnth0

nth1(Idx,List,X) :-
    Idx0 is Idx-1,
    nth0(Idx0,List,X).

編集nth0:ほんの数行のコードなしで行うことも可能です:

nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
    Idx > 1,
    Idx1 is Idx-1,
    nth1(Idx1,List,X).
于 2010-11-21T12:04:40.037 に答える
2

私は矛盾したり、他の誰かに私の仕事を実際にやらせたりするつもりはありませんでした。はっきりしないことをお詫び申し上げます。

私は今それを自分で実装しましたが、皆さんはおそらくそれを行うための改善またはより良い方法を提案できますか?私がPrologでよくやっていることは、たとえばカウンターまたはカウンターのセットを使用して述語を記述し、追加の引数を使用して句を呼び出すために、より少ない引数を使用して述語を取得することです。これにより、かなりの量のコードが生成されることがよくあります。とにかく、これが私が今やった私の実装です:

item_at( N, L, Item ) :-
    item_at( N, 0, L, Item ).   
item_at( N, Count, [H|_], Item ) :-
    CountNew is Count + 1,
    CountNew = N,
    Item = H.
item_at( N, Count, [_|T], Item ) :-
    CountNew is Count + 1,
    item_at( N, CountNew, T, Item ).

コメントはありますか?ありがとう :)。使用法:

?- item_at(3,[a,b,c,d,e],Item).
Item = c ;
于 2010-11-21T12:34:40.980 に答える