Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- % Состояние кувшинов [v1, v2, ...]
- % Емкость кувшинов [c1, c2, ...]
- solve(Cs, V, Moves) :-
- abolish(move, 2),
- abolish(capacity, 2),
- length(Cs, L),
- prepair_cs(Cs, 1),
- prepair(L, 1),
- prepair(L, 1, 1),
- make_zero(Zero, L),
- solve(V, Zero, [Zero], Moves).
- solve(V, State, _, []) :-
- member(V, State).
- solve(V, State, History, [Move|Moves]) :-
- move(State, Move),
- update(State, Move, State1),
- not(member(State1, History)),
- solve(V, State1, [State|History], Moves).
- prepair(L, L) :-
- assert(:-(move(State, fill(L)), (get_val(State, L, V), capacity(L, C), C \= V))),
- assert(:-(move(State, empty(L)), (get_val(State, L, V), 0 \= V))).
- prepair(L, I) :- I < L, I1 is I + 1,
- assert(:-(move(State, fill(I)), (get_val(State, I, V), capacity(I, C), C \= V))),
- assert(:-(move(State, empty(I)), (get_val(State, I, V), 0 \= V))), prepair(L, I1).
- prepair(L, L, L) :- !.
- prepair(L, L1, L2) :- L1 > L, L3 is L2 + 1, prepair(L, 1, L3).
- prepair(L, L1, L2) :- L1 =< L, L2 =< L, L11 is L1 + 1, L1 \= L2,
- assert(:-(move(State, trans(L1, L2)),
- (
- get_val(State, L1, V1), V1 \= 0,
- get_val(State, L2, V2), capacity(L2, C2), V2 \= C2
- )
- )), prepair(L, L11, L2).
- prepair(L, L1, L2) :- L1 =< L, L2 =< L, L11 is L1 + 1, L1 = L2, prepair(L, L11, L2).
- prepair_cs([], _).
- prepair_cs([C|Cs], I) :- I1 is I + 1, assert(capacity(I, C)), prepair_cs(Cs, I1).
- update(State, empty(X), State1) :- set_val(State, X, 0, State1).
- update(State, fill(X), State1) :- capacity(X, C), set_val(State, X, C, State1).
- update(State, trans(X, Y), State1) :- get_val(State, X, From), get_val(State, Y, To),
- capacity(Y, CTo), adjust(From, To, CTo, RFrom, RTo),
- set_val(State, X, RFrom, State2), set_val(State2, Y, RTo, State1).
- set_val([_|Es], 1, Val, [Val|Es]).
- set_val([E|Es], Pos, Val, [E|Es1]) :- Pos > 1, Pos1 is Pos - 1, set_val(Es, Pos1, Val, Es1).
- get_val([E|_], 1, E).
- get_val([_|Es], Pos, Val) :- Pos > 1, Pos1 is Pos - 1, get_val(Es, Pos1, Val).
- adjust(From, To, CTo, 0, RTo) :- RTo is From + To, RTo =< CTo.
- adjust(From, To, CTo, RFrom, CTo) :- RTo1 is From + To, RTo1 > CTo, RFrom is RTo1 - CTo.
- make_zero([], 0).
- make_zero([0|Zs], L) :- L1 is L - 1, make_zero(Zs, L1).
Add Comment
Please, Sign In to add comment