Reputation: 494
I'm trying to rotate a list in prolog recursively but it does not work as expected.
Code:
rot([],[]).
rot([H|T1], [T2|H]):-rot(T1,T2).
Output:
?- rot([1,2,3], V).
V = [[[[]|3]|2]|1]
Expected output:
?- rot([1,2,3], V).
V = [3,2,1]
Could anyone explain me why my code does not work?
Upvotes: 2
Views: 302
Reputation: 1429
The problem is with the second clause. What I do is to rotate the tail of the first list inside L1 and then call append
with L1 and the first element and assign the result to L (the second argument)
my-append([], L, L).
my-append([H|T], L, [H|R]) :- my-append(T, L, R).
rot([], []).
rot([H|T], L) :- rot(T, L1), my-append(L1, H, L).
Upvotes: 2
Reputation: 476614
Since Prolog is untyped, you can indeed write something like [List|Element]
, but if you want a list to make sense, the only way you can construct lists is like [Element|List]
. So [T2|H]
does not make sense at all. In that case T2
should be an element, and H
a list (or the empty list []
).
You will need to define two predicates:
rot/2
) that simply pops the head from the given list and calls the recursive predicate; androt/3
) that simply passes all elements of the given list and emits the original head as tail element.Together this works like:
%main predicate rot/2
rot([],[]).
rot([H|T1],T2) :-
rot(T1,H,T2).
%recursive predicate rot/3
rot([],Last,[Last]).
rot([H|T1],Last,[H|T2]) :-
rot(T1,Last,T2).
Upvotes: 4
Reputation: 22803
Your code doesn't work because in an expression like [H|T]
, H
is an element of the list and T
is the tail of the list--also a list. For instance:
?- [H|T] = [1,2,3].
H = 1,
T = [2, 3].
So what happens when you switch that around?
?- [H|T] = [1,2,3], X = [T|H].
H = 1,
T = [2, 3],
X = [[2, 3]|1].
See the problem?
Upvotes: 3