% Water Jugs puzzle

:- ensure_loaded(solver).

%% pour from 8 to 5
jugs(N8, N5, N3) => jugs(M8, M5, N3) :-
    N8 > 0,
    S5 is 5 - N5,
    min(N8, S5, T),
    T > 0,
    M8 is N8 - T,
    M5 is N5 + T.    

%% pour from 8 to 3
jugs(N8, N5, N3) => jugs(M8, N5, M3) :-
    N8 > 0,
    S3 is 3 - N3,
    min(N8, S3, T),
    T > 0,
    M8 is N8 - T,
    M3 is N3 + T.    

%% pour from 5 to 3
jugs(N8, N5, N3) => jugs(N8, M5, M3) :-
    N5 > 0,
    S3 is 3 - N3,
    min(N5, S3, T),
    T > 0,
    M5 is N5 - T,
    M3 is N3 + T.    

%% pour from 5 to 8
jugs(N8, N5, N3) => jugs(M8, M5, N3) :-
    N5 > 0,
    S8 is 8 - N8,
    min(N5, S8, T),
    T > 0,
    M5 is N5 - T,
    M8 is N8 + T.    

%% pour from 3 to 8
jugs(N8, N5, N3) => jugs(M8, N5, M3) :-
    N3 > 0,
    S8 is 8 - N8,
    min(N3, S8, T),
    T > 0,
    M3 is N3 - T,
    M8 is N8 + T.    

%% pour from 3 to 5
jugs(N8, N5, N3) => jugs(N8, M5, M3) :-
    N3 > 0,
    S5 is 5 - N5,
    min(N3, S5, T),
    T > 0,
    M3 is N3 - T,
    M5 is N5 + T.    


min(A, B, Min) :-
    A =< B,
    Min is A.
min(A, B, Min) :-
    A > B,
    Min is B.

final(jugs(4, _N5, _N3)).

final(jugs(_N8, 4, _N3)).

initial(jugs(8, 0, 0)).

