Prolog,如何访问列表中的特定成员?

26

请问有人知道如何在Prolog中访问列表的特定成员吗?例如,如果我需要访问传递到规则中的列表的第三个或第四个元素怎么办?

4个回答

33

nth0(Ind, Lst, Elem)nth1(Ind, Lst, Elem) 在 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.

如果我制定了一个规则,需要将某个元素与传递进来的列表中的特定元素统一起来,我该如何使用它? - David Carpenter
2
以下是使用示例: ?- L = [a,b,c], nth0(Ind, L, a),nth0(2, L, X).
L = [a,b,c],
Ind = 0,
X = c . 或者 ?- L = [a,b,c], nth1(Ind, L, a), nth1(2, L, X).
L = [a,b,c],
Ind = 1,
X = b .
- joel76

6

当需要访问的索引非常小的时候,可以使用模式匹配。比如说我们需要第三个元素或者第四个:

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

这可能更有用,如果它被“内联”使用,在列表携带具有位置相关性的信息时。例如:
your_rule([_,_,E|Rest], Accum, Result) :-
   Sum is Accum + E,
   your_rule(Rest, Sum, Result).
...

1

Prolog列表是经典的列表。访问不是直接的,您必须迭代才能找到所需内容。

您可以通过以下方式获取第n个元素:

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

其中 [code]X[/code]n 是列表的第 n 个元素。当 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)。

0

使用func库可以更简洁地编写SWI-Prolog中的列表推导式:

:- use_module(library(func)).

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

现在,您可以像这样访问列表的两个元素并将它们相加:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接