Translating a list to another list in prolog

957 Views Asked by At

I Tried to write a simple code in Prolog which translate a list to another list. for instance, if we call listtrans([a,b,c],L), L will become [1,2,3]. (a,b,c is replaced with 1,2,3). But i faced with a syntax error in last line. what is the problem? here is my code:

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).
2

There are 2 best solutions below

0
On BEST ANSWER

The error is very likely because in your code:

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

the variable L1 is declared in the head, but not referenced anywhere: you mispelled something?

Anyway, your code is not going to work.

Moreover, using append/3 for this kind of tasks which are easily defined by recursion is considered terrible (also because of the bad performance you get out of it).

Applying a function to a list is straightforward. You already know that in prolog you don't write Y = f(X) but rather declare the functional relation between X and Y as: f(X, Y).. (That's basically what you did with trans(X,Y)).

Now the (easy) recursive formulation:

  • the transformed empty list is the empty list
  • the transformation of [X|Xs] is [Y|Ys] if trans(X,Y) and we recursively transform Xs into Ys

or expressed in prolog:

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

I recommend you reading the first 4 chapters of Learn Prolog Now to better understand these concepts.

0
On

There are no syntactic errors, only semantic ones. This is it, with corrections:

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

But this is not Prolog style. One writes rather:

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

Note that in Prolog explicitly appending elements is much rarer than in languages supporting functions. As an extra bonus, you can now use the relation in both directions:

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

And you can write this more compactly:

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

See this for more.