solve(State, Goal, Plan, Plan):- subset(Goal, State). solve(State, Goal, Sofar, Plan):- opn(Op, Precons, Delete, Add), is_subset(Precons, State), can(Op, State), notmember(Op, Sofar), delete_list(Delete, State, Remainder), append(Add, Remainder, NewState), solve(NewState, Goal, [Op|Sofar], Plan). opn(grab(B), [on(monkey,box), at(box, X), at(B,X), status(B,hanging)], [status(B,hanging)], [status(B,grabbed)]). opn(climb(B), [at(monkey,X), at(B, X), on(monkey,floor)], [on(monkey,floor)], [on(monkey,B)]) :- member(B, [box]). opn(push(B,From,To), [at(monkey, From), at(B,From), on(monkey,floor)], [at(monkey, From), at(B,From)], [at(monkey, To), at(B, To)]) :- member(B, [box]), member(To, [a,b,c]). opn(go(From,To), [at(monkey, From), on(monkey,floor)], [at(monkey, From)], [at(monkey, To)]) :- member(To, [a,b,c]). can(grab(_), _). can(climb(B), State) :- subset([at(B,X), at(banana,X)], State). can(push(_,From,To), State) :- From \= To, member(at(banana,To), State). can(go(From,To), State) :- From \= To, member(at(box,To), State). notmember(X,Y):- not(member(X,Y)). delete_one(A,[A|Y], Y) :- !. delete_one(A, [B|Y], [B|U]) :- delete_one(A,Y,U). delete_list([], X, X). delete_list([A|X], Y, Z) :- delete_one(A,Y,U), delete_list(X,U,Z). is_subset([], Y). is_subset([A|X],Y) :- member(A,Y), is_subset(X,Y). test(Plan):- solve([ at(monkey,a), at(box,b), at(banana, c), on(monkey,floor), status(banana, hanging)], [ status(banana,grabbed)], [], Plan).