将一个列表翻译成序言中的另一个列表

Translating a list to another list in prolog

我试图在 Prolog 中编写一个简单的代码,将一个列表转换为另一个列表。例如,如果我们调用 listtrans([a,b,c],L)L 将变为 [1,2,3]。 (a、b、c 替换为 1、2、3)。但是我在最后一行遇到语法错误。问题是什么?这是我的代码:

trans(a,1).
trans(b,2).
trans(c,3).

listtrans([],L).
listtrans([H|T],L1):-
   trans(H,B),
   append(B,L,L2),
   listtrans(T,L2).

没有语法错误,只有语义错误。就是这样,有更正:

listtrans([],[]).
listtrans([H|T],L1):-
   trans(H,B),
   append([B],L2,L1),
   listtrans(T,L2).

但这不是序言风格。一个人写道:

listtrans([],[]).
listtrans([A|As],[I|Is]):-
   trans(A,I),
   listtrans(As,Is).

请注意,在 Prolog 中显式附加元素比在支持函数的语言中要少得多。作为额外的奖励,您现在可以在两个方向上使用关系:

?- listtrans([a,b,c],Is).
Is = [1,2,3].

?- listtrans(As, [1,2,3]).
As = [a,b,c].

你可以写得更紧凑:

listtrans(As, Is) :-
   maplist(trans, As, Is).

有关更多信息,请参阅 this

这个错误很有可能是因为在你的代码中:

listtrans([H|T],L1):-
   trans(H,B),
   append(B,L,L2),
   listtrans(T,L2).

变量 L1 在头部声明,但没有在任何地方引用:你拼错了什么?

无论如何,您的代码无法正常工作。

此外,对于这种很容易通过递归定义的任务,使用 append/3 被认为是 糟糕的 (也是因为你从中得到的糟糕表现) .

将函数应用于列表很简单。您已经知道在序言中您不写 Y = f(X) 而是将 XY 之间的 函数关系 声明为: f(X, Y).. (这基本上就是你对 trans(X,Y) 所做的)。

现在是(简单的)递归公式:

  • 转换后的空表就是空表
  • 如果trans(X,Y)[X|Xs]的变换是[Y|Ys],我们递归地把Xs变换成Ys

或者用序言表示:

listtrans([],[]).
listtrans([X|Xs],[Y|Ys]) :- trans(X,Y), listtrans(Xs,Ys).

我建议您阅读 Learn Prolog Now 的前 4 章以更好地理解这些概念。