0

我在 prolog 中有一个小规则,它必须检查一个元素是否是列表的成员并将它的位置写在列表中,但它只有在我正在寻找的 elemebt 位于第一个地方时才有效。需要帮助!

write_element(X,[X|_],1).
write_element(X,[_|Tail],N):-
N1 is N-1,
write_element(X,Tail,N1).
4

2 回答 2

1

这个东西到底应该怎么称呼?似乎 N 必须由我实例化,否则N1 is N-1将不起作用。但同样,在您的基本情况下,N 必须与 1 统一,因此如果 X 存在于列表中,则 N 必须等于 1。所以我认为你对如何调用它有一些基本的困惑。如果您想使用 N 作为计数器,您可能不能也将其用作变量。不过,您应该重新考虑递减的想法,因为我认为没有任何理由期望它以适合递减的大值被调用,除非length/2您的代码中有其他地方您没有共享。

您的第二个问题是这不会在任何地方写任何东西,并且由于您没有包含实际的问题陈述,我将不得不猜测您可能真正想要做的只是返回位置,例如nth1/3. nth1/3如果您只想在元素存在时打印出位置,我们可以使用它来实现:

write_element(X, L, N) :- nth1(N, L, X), write(N).

赔率很好,这不是预期的。如果你想实现类似nth1/3的东西,它会更有趣,因为我们需要将我们返回的计数器与我们正在使用的计数器分开。所以它最终看起来像这样:

write_element(X,L,N) :- write_element_loop(X,L,1,N).

write_element_loop(X, [X|_] , N,  N).
write_element_loop(X, [_|Xs], N0, N) :-
    N1 is N0+1,
    write_element_loop(X, Xs, N1, N).

这实际上非常接近您的代码,我刚刚明确区分了计数器和返回值。如果您想打印这些值而不是统一它们,您可以将其添加到第一条规则的末尾:

write_element_loop(X,[X|_],N,N) :- write(N), nl.

希望这可以帮助!

于 2013-05-07T01:59:46.153 回答
1

由于您报告它仅适用于第一个位置,因此可以对您的代码进行更简单的更正以使其在其他情况下工作:

write_element(X,[X|_],1).
write_element(X,[_|Tail],N):-
  write_element(X,Tail,N1),
  N is N1 + 1.

但是丹尼尔(+1)的答案是你应该学习的。

于 2013-05-07T05:23:49.503 回答