Fabiola Salomone
Fabiola Salomone

Reputation: 13

Prolog write predicate that decrements all elements of a list of integers

as the title suggests, I have to write a predicate that decreases all the values of a list. I did this but I am not convinced can you help me?

decremento([ ],[ ]).
decremento([H | T], L):- decremento(T,N), L is N-1.

Upvotes: 1

Views: 207

Answers (2)

TA_intern
TA_intern

Reputation: 2436

From the comment to another answer:

maplist(plus(-1), Xs, Ys)
?- maplist(plus(-1), [1,2,3], Ys).
Ys = [0, 1, 2].

?- maplist(plus(-1), Xs, [1,2,3]).
Xs = [2, 3, 4].

?- maplist(plus(-1), [1,X], [Y,2]).
X = 3,
Y = 0.

Upvotes: 1

Nicholas Carey
Nicholas Carey

Reputation: 74287

So the problem statement is to traverse a list of [presumably] numbers, decrementing each one?

So... something like this —

decremento( []     , []     ) .  % the list is empty, nothing to decrement
decremento( [X|Xs] , [Y|Ys] ) :- % the list is non-empty, so...
  Y is X-1,                      % - decrement the head of the list,
  decremento(Xs,Ys)              % - recurse down
  .                              % Simple!

Running the above:

decremento( [1,2,3] , X ).

yields the desired

X = [0, 1, 2]

But... what about the other way?

decremento(X,[0,1,2]).

Sadly, that give us

Arguments are not sufficiently instantiated
In:
   [2] 1 is _1632-1
   [1] decremento([_1694|_1696],[1,2|...]) at  line 3

We need to do a little type checking to be it work both ways. So, something like this will work properly.

  • decremento([1,2,3],X) yields X = [0,1,2]
  • decremento(X,[0,1,2]) yields X = [1,2,3]
  • decremento([1,2,3],[0,1,2]) yields true.
decremento( Xs, Ys ) :- nonvar(Xs), !, add_list(-1,Xs,Ys) .
decremento( Xs, Ys ) :- nonvar(Ys), !, add_list(+1,Ys,Xs).

add_list( _, []     , []     ) .
add_list( N, [X|Xs] , [Y|Ys] ) :- Y is X+N, add_list(N,Xs,Ys).

Upvotes: 1

Related Questions