% Rotate a list N places to the left
% rotate(L1,N,L2) :- the list L2 is obtained from the list L1 by
% rotating the elements of L1 N places to the left.
% Examples:
% rotate([a,b,c,d,e,f,g,h],3,[d,e,f,g,h,a,b,c])
% rotate([a,b,c,d,e,f,g,h],-2,[g,h,a,b,c,d,e,f])
% (list,integer,list) (+,+,?)
% Split a list into two parts
% split(L,N,L1,L2) :- the list L1 contains the first N elements
% of the list L, the list L2 contains the remaining elements.
% (list,integer,list,list) (?,+,?,?)
domains
list=symbol*
predicates
rotate(list,integer,list).
length(list,integer).
rotate_left(list,integer,list).
append(list,list,list).
split(list,integer,list,list).
clauses
rotate(L1,N,L2) :- N >= 0,
length(L1,NL1), N1 = N mod NL1, rotate_left(L1,N1,L2).
rotate(L1,N,L2) :- N < 0,
length(L1,NL1), N1 = NL1 + (N mod NL1), rotate_left(L1,N1,L2).
rotate_left(L,0,L).
rotate_left(L1,N,L2) :- N > 0, split(L1,N,S1,S2), append(S2,S1,L2).
append([],Listb,Listb).
append([X|List1],List2,[X|List3]):-
append(List1,List2,List3).
split(L,0,[],L).
split([X|Xs],N,[X|Ys],Zs) :- N > 0, N1 = N - 1, split(Xs,N1,Ys,Zs).
length([],0).
length([_|L],N) :- length(L,N1), N = N1 + 1.
--------------------------------------------------------
Goal: rotate([a,b,c,d,e,f,g,h],3,X)
X=(["d","e","f","g","h","a","b","c"])
1 solution