Search code examples
prologfailure-slice

Prolog - Increase all the numbers of a list by 1


I tried this

 fun([],[]).
 fun([A|_],B) :- number(A), B is A +1,!.
 fun([H|T],R) :- fun(T,R).

I know it's wrong, could you help me? Thanks


Solution

  • The problem is that you're not consistent and you're not finishing the recursion.

    With your code, something like this is true:

    fun([a,b,c],X) .
    

    and will result in X having the value [], but

    fun([a,1,b],X) .
    

    will result in X having the value 2.

    If you want to find the first number in the list and increment it by one, something like this will do:

    fun([X|Xs],Y) :- number(X) , ! , Y is X+1 .
    fun([_|Xs],Y) :- fun(Xs,Y) .
    

    If you want to increment each number in the list, then try something like this:

    fun( []    , []      ) .  % if the source list is exhausted, we're done.
    fun( [X|Xs] , [Y|Ys] ) :- % otherwise,
      number(X) ,             % - if X is a number,
      Y is A+1                % - we increment it to get Y
      fun( Xs , Ys ) .        % - and recurse down on the tails of the respective lists
    fun( [X|Xs] , [X|Ys] ) :- % otherwise, add X to the result list
      \+ number(X) ,          % - assuming X is not a number,
      fun(Xs,Ys) .            % - and recurse down.
    

    You should not that this could be more concisely states as

    fun( [] , [] ) :-
    fun( [X|Xs] , [Y|Ys] ) :-
      increment(X,Y) ,
      fun( Xs , Ys )
      .
    
    increment(X,Y) :- number(X) , ! , Y is X+1 .
    increment(X,X) .
    

    Or, more concisely yet

    fun( [] , [] ) .
    fun( [X|Xs] , [Y|Ys] ) :-
      ( number(X) -> Y is X+1 ; Y = X ) ,
      fun(Xs,Ys).
    

    The A -> B ; C construct is the implication operator.