action(put_on_table(X), S, [on(X, table) | S1]) :- block(X), not(member(on(_, X), S)), not(member(on(X, table), S)), pick_up(X, S, S1). action(move(X, Y, Z), S, [on(X, Z) | S1]) :- member(on(X, Y), S), not(member(on(_, X), S)), block(Z), Z \== X, not(member(on(_, Z), S)), pick_up(X, S, S1). pick_up(X, [on(X, _) | Rest], S) :- pick_up(X, Rest, S). pick_up(X, [on(Y, Z) | Rest], [on(Y, Z) | S]) :- X \== Y, X \== Z, pick_up(X, Rest, S). pick_up(_, [], []). block(X) :- member(X, [a, b, c]). initial([on(c, a), on(a, b), on(b, table)]). goal([on(a, b), on(b, c), on(c, table)]).