web-dev-qa-db-ja.com

プロローグ、リストの特定のメンバーにアクセスしますか?

プロローグのリストの特定のメンバーにアクセスする方法を誰かに教えてもらえますか?たとえば、ルールに渡されたリストの3番目または4番目の要素にアクセスする必要があるとしましょう。

18
David Carpenter

nth0(Ind, Lst, Elem)またはnth1(Ind, Lst, Elem) with SWI-Prolog、nth0最初の要素のインデックスは0です。

例えば、

nth0(3, [a, b, c, d, e], Elem). %Binds d to Elem
nth1(3, [a, b, c, d, e], Elem). %Binds c to Elem

nth0(Ind, [a, b, c, d, e], d).  %Binds 3 to Ind
nth0(3, [a, b, c, X, e], d).    %Binds d to X

nth0(3, [a, b, c, d, e], c).    %Fails.
26
joel76

アクセスする必要があるインデックスが非常に小さい場合は、パターンマッチングを使用できます。 3番目の要素または4番目の要素が必要だとします。

third([_,_,E|_], E).
fourth([_,_,_,E|_], E).

これは、リストが位置的関連性のある情報を運ぶ場合、「インライン」を使用した場合により役立ちます。例えば

your_rule([_,_,E|Rest], Accum, Result) :-
   Sum is Accum + E,
   your_rule(Rest, Sum, Result).
...
7
CapelliC

プロローグリストは古典的なリストです。アクセスは直接ではありません。あなたはあなたが必要なものを見つけるために反復する必要があります。

このようにして、n番目の要素を取得できます。

foo( [X1,X2,X3,X4,...,XN|Xs] ) :- ...

ここで、[コード] X [/コード] リストのnth要素です。 nが小さい値よりも大きい場合は実用的ではありません。これは、C/C++ポインター式にほぼ類似しています。

LLNode *nthElement = root->next->...->next ;

それ以外の場合は、次のような組み込みの述語または自家製の述語を使用して、目的の要素を見つけるためにリストを反復処理する必要があります。

foo(Xs):-nth_element(Xs、9、X)、...

nth_element(Xs、N、X):-nth_element(Xs、0、N、X)。

nth_element([X | Xs]、N、N、X):-!。 nth_element([_ | Xs]、T、N、X):-T1はT + 1、nth_element(Xs、T1、N、X)です。

2
Nicholas Carey

SWI-Prologの func ライブラリを使用すると、リストの内包表記をより簡潔な方法で記述できます。

:- use_module(library(func)).

nth0((Index, List), Result) :-
    nth0(Index,List,Result).

これで、リストの2つの要素にアクセスして、次のようにまとめて追加できます。

example :-
    List = [1,5,12,9],
    Y is (nth0 $ (0, List)) + (nth0 $(3,List)), %add the 1st and 4th elements of this list
    writeln(Y). %prints 10
0
Anderson Green