Prolog: Reverse every second list elements in a list?

Since you said that add/3 fails after the second iteration I assume that you used trace/0 anyway, here it is.

DoStuff(1,2, 3,4, 5,6, 7,8, R). Call: (6) doStuff(1, 2, 3, 4, 5, 6, 7, 8, _G405)? Creep Call: (7) lists:reverse(3, 4, _G496)?

Creep Exit: (7) lists:reverse(3, 4, 4, 3)? Creep Call: (7) add(1, 2, 4, 3, _G405)? Creep Exit: (7) add(1, 2, 4, 3, 1, 2, 4, 3)?

Creep Call: (7) doStuff(5, 6, 7, 8, 1, 2, 4, 3)? Creep Call: (8) lists:reverse(7, 8, _G514)? Creep Exit: (8) lists:reverse(7, 8, 8, 7)?

Creep Call: (8) add(5, 6, 8, 7, 1, 2, 4, 3)? Creep Fail: (8) add(5, 6, 8, 7, 1, 2, 4, 3)? Creep Redo: (7) doStuff(5, 6, 7, 8, 1, 2, 4, 3)?

Creep Fail: (7) doStuff(5, 6, 7, 8, 1, 2, 4, 3)? Creep Redo: (6) doStuff(1, 2, 3, 4, 5, 6, 7, 8, _G405)? Creep Fail: (6) doStuff(1, 2, 3, 4, 5, 6, 7, 8, _G405)?

Creep false. So why does it fail? It's because of one of prolog's main characteristics basically, a variable in prolog, once it takes a value, it can never change this may sound kinda weird if you used imperative languages so far but consider that exactly the same thing happens in math.

For example, consider the following equations: x+3=4 4-x=5 from the first we get that x=1 and from the second we get that x=-1 since x cannot be 1 and -1 we say that there is no x to satisfy the equations above; not that x is -1 since that's the value of the second (and last) equation exactly the same thing happens in yout program: doStuff(X,S|T,R):- reverse(S,Rev), add(X,Rev,R), doStuff(T,R). So the first time R is assigned a value and the doStuff/2 is call with a value for R. Obviously, this is not the correct value so doStuff/2 fails so how can you fix this?

Look at the way you wrote X,S|T to separate the first two elements that you wanted to process. You only have to do exactly the same with the result: write it like XResult,SResult|Rest of course XResult will be simply X and SResult will be the reverse of S (Rev) Rest will be what you get from the recursive call of doStuff/2 last but not least you should check the clauses that are called in the end. You could check some stuff about lists and recursion.

Thanks for the answer. I've been trying to implement it in the past few days. So my problem is that the R variable already has a value in the second iteration when the add function tries to change it.So I would need to use temporary variable.

This is what I wrote based on your answer. It returns but does not return the result list. DoStuff(X,S|T,R):- reverse(S,Rev), add(X,Rev,XResult,SResult|Rest), doStuff(T,XResult,SResult|Rest).

What am I doing wrong? Thanks again. – eidolon May 16 at 15:46 you shouldnt pass XResult,SResult to the recursive call of doStuff/2 instead, you just call doStuff(T,Rest).

The result list is R so you shall define what R is. For example, you can write R=X,Rev|Rest.So basically you have this: doStuff(X,S|T,R):- reverse(S,Rev), doStuff(T,Rest), R=X,Rev|Rest. Since you don't use R anywhere else you can simply write: doStuff(X,S|T,X,Rev|Rest):- reverse(S,Rev), doStuff(T,Rest).

– thanosQR May 16 at 17:05 okay, now I see what you meant before, don't need the add function. Thank you, I really appreciate it. – eidolon May 16 at 18:15.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions