【Prolog】Prologへの入門 3章(続き)

% 3.3
evenlength([]).
evenlength([X|L]) :- oddlength(L).

oddlength([_]).
oddlength([X|L]) :- evenlength(L).

% 3.4
conc([], L, L).
conc([X|L1], L2, [X|L3]) :- conc(L1, L2, L3).
reverse([], []).
reverse([X|L1], L) :- reverse(L1, L2), conc(L2, [X], L).

% 3.5
palindrome(List) :- reverse(List, List).

% 3.6
shift([], []).
shift([X|L1], L) :- conc(L1, [X], L).

% 3.7
means(0, zero).
means(1, one).
means(2, two).
means(3, three).
means(4, four).
means(5, five).
means(6, six).
means(7, seven).
means(8, eight).
means(9, nine).
translate([], []).
translate([X|L1], [X1|L]) :- means(X, X1), translate(L1, L).

% 3.8
subset([], []).
subset([X|L1], [X|L2]) :- subset(L1, L2).
subset([X|L1], L2) :- subset(L1, L2).

% 3.9
dividelist([], [], []).
dividelist([X], [X], []).
dividelist([X, Y|L], [X|L1], [Y|L2]) :- dividelist(L, L1, L2).

% 3.10
move(state(middle, onbox, middle, hasnot), grasp, state(middle, onbox, middle, has)).
move(state(P, onfloor, P, H), climb, state(P, onbox, P, H)).
move(state(P1, onfloor, P1, H), push(P1, P2), state(P2, onfloor, P2, H)).
move(state(P1, onfloor, B, H), walk(P1, P2), state(P2, onfloor, B, H)).
canget(state(_, _, _, has), []).
canget(State1, [Move|L]) :- move(State1, Move, State2), canget(State2, L).

% 3.11
/* これだと?- flatten([1], L).などで無限ループになってしまう
flatten([X|L1], L2) :- flatten([X], L3), flatten(L1, L4), conc(L3, L4, L2).
flatten([], []).
*/

flatten([X|L1], L2) :- flatten(X, L3), flatten(L1, L4), conc(L3, L4, L2).
flatten([], []).
flatten(X, [X]).