:- ['special_flux']. poss(pickup(B,R), Z) :- holds(empty(B), Z), holds(at(R1), Z), holds(request(R1,R), Z). poss(deliver(B), Z) :- holds(at(R), Z), holds(carries(B,R), Z). state_update(Z1, go(D), Z2) :- holds(at(R), Z1), ( D = up -> R1 is R + 1 ; R1 is R - 1 ), update(Z1, [at(R1)], [at(R)], Z2). state_update(Z1, pickup(B, R), Z2) :- holds(at(R1), Z1), update(Z1, [carries(B,R)], [empty(B),request(R1,R)], Z2). state_update(Z1, deliver(B), Z2) :- holds(at(R), Z1), update(Z1, [empty(B)], [carries(B,R)], Z2). init(Z0,Max) :- create_requests(0, Z, Max), Z0 = [at(1),empty(bag1),empty(bag2),empty(bag3) | Z]. main(Max) :- init(Z,Max), main_loop(Z). main_loop(Z) :- poss(deliver(B), Z) -> execute(deliver(B), Z, Z1), main_loop(Z1) ; poss(pickup(B,R), Z) -> execute(pickup(B,R), Z, Z1), main_loop(Z1) ; continue_delivery(D, Z) -> execute(go(D), Z, Z1), main_loop(Z1) ; true. continue_delivery(D, Z) :- ( holds(empty(_), Z), holds(request(R1,_), Z) ; holds(carries(_,R1), Z) ), holds(at(R), Z), ( R < R1 -> D = up ; D = down ). create_requests(Max,[],Max) :- !. create_requests(N,Z,Max) :- N1 is N+1, create_request(N1,0,Z1,Max), create_requests(N1,Z2,Max), append(Z1,Z2,Z). create_request(_,Max,[],Max) :- !. create_request(N,M,Z,Max) :- M1 is M+1, create_request(N,M1,Z1,Max), ( M1 \= N -> Z = [request(N,M1)|Z1] ; Z = Z1 ).