%%=====================================================
%% Solution to the Man-Wolf-Goat-Cabbage Puzzle (15/4/2022)
%%=====================================================

solve(Moves) :-
    length(Moves, _), initial(C), solve(C, Moves).

/* solve(+Config, ?Moves) */
solve(Config, []) :- final(Config).
solve(Config, [Move | Moves]) :-
    move(Config, Move, NewConfig),
    safe(NewConfig),
    solve(NewConfig, Moves).

safe(config(Man, Wolf, Goat, Cabbage)) :-
    together_or_separated(Man, Wolf, Goat),
    together_or_separated(Man, Goat, Cabbage).

together_or_separated(Coast, Coast, Coast).  % together
together_or_separated(_, Coast1, Coast2) :- opposite(Coast1, Coast2).

/*
** The representation of the configurations is
**    config(Man, Wolf, Goat, Cabbage)
*/

initial(config(w, w, w, w)).
final(config(e, e, e, e)).

/* move(Conf1, Move, Conf2) */
move(config(Coast, Coast, G, C), wolf, config(OppositeCoast, OppositeCoast, G, C)) :-
    opposite(Coast, OppositeCoast).
move(config(Coast, W, Coast, C), goat, config(OppositeCoast, W, OppositeCoast, C)) :-
    opposite(Coast, OppositeCoast).
move(config(Coast, W, G, Coast), cabbage, config(OppositeCoast, W, G, OppositeCoast)) :-
    opposite(Coast, OppositeCoast).
move(config(Coast, W, G, C), nothing, config(OppositeCoast, W, G, C)) :-
    opposite(Coast, OppositeCoast).

opposite(w, e).
opposite(e, w).


%%=====================================================
%% Solution to the Eight Queens problem
%%=====================================================

eightqueens(Queens) :-
    Queens = [1/_, 2/_, 3/_, 4/_, 5/_, 6/_, 7/_, 8/_],
    qsafe(Queens).

qsafe([]).
qsafe([X/Y | Rest]) :-
    qsafe(Rest),
    % member(X, [1,2,3,4,5,6,7,8]),
    member(Y, [1,2,3,4,5,6,7,8]),
    nocheck(Rest, X/Y).

/* nocheck(+Queens, +Queen) */
nocheck([], _).
nocheck([X1/Y1 | Rest], X/Y) :-
    % X =\= X1,
    Y =\= Y1,
    abs(Y1-Y) =\= abs(X1-X),
    nocheck(Rest, X/Y).
