0
votes

Say I have a list

[5,4,6,9]

And I want to take away from the head of the list but return the rest of the list

so: -3

[2,4,6,9]

-2

[3,4,6,9]

And then I want to move on to the next element so,

-3

[5,1,6,9],

-2

[5,2,6,9]

How could I produce a prolog predicate for this,

so far I have

 change([],[]).
change([Head|Tail], [Head1|Tail]):-
    process(Head, Head1).


process([],[]).
process(Head, Head1):-
    Head1 is Head-3,
    Head1 >=0.

process(Head, Head1):-
    Head1 is Head-2,
    Head1 >=0.

I'm unsure what I'd return in my recursive call, any help would be great thank you

1
You want to change only head and second element and leave other list as it is? And also you want to do this only with -2,-3 or with a given number?? - coder
I want to remove -2 and -3 from each element in the list individually @coder - user3667111
But in your example what should be the output with input [5,4,6,9]?? (you describe some changes but what is the expected output exactly??) - coder
So I want it to show all possible states, so starting state is [5,4,6,9], then I want it to remove -2 and -3 from 5 individually so [3,4,6,9] , [2,4,6,9], [5,2,6,9] ,[5,1,6,9], [5,4,4,9] ,[5,4,3,9] [5,4,6,7] ,[5,4,6,6] @coder - user3667111
@coder, the example I have added works perfectly for the first element, just unsure how to move on to the next one - user3667111

1 Answers

2
votes

The way your code is currently written it's attempting to change more than one list element in a given solution. However, the requirement appears to be to only change one list element. Using CLP(FD) will help with the arithmetic.

change([], []).           % Nothing to change
change([X|T], [Y|T]) :-   % Change only the head
    Y #= X - 2 ; Y #= X - 3.
change([X|Xs], [X|Ys]) :- % Keep the head and change something later
    change(Xs, Ys).

The potential problem with this solution is that it change(L, L). is true (the list isn't changed). To avoid that, you can change the base case to be for the single element list and force the others to be two elements:

change([X], [Y]) :-             % Change only the last or single element
    Y #= X - 2 ; Y #= X - 3.
change([X,X1|Xs], [Y,X1|Xs]) :- % Change only the head
    Y #= X - 2 ; Y #= X - 3.
change([X,X1|Xs], [X,Y1|Ys]) :- % Keep the head and change something later
    change([X1|Xs], [Y1|Ys]).