% Bad Situations for a Simple Blocks World % Don't create a bad tower by a move action. badSituation(do(move(X,Y),S)) :- not goodTower(X,do(move(X,Y),S)). % Don't move anything from a good tower to the table. badSituation(do(moveToTable(X),S)) :- goodTower(X,S). /* Opportunistic rule: If an action can create a good tower, don't do a bad-tower-creating moveToTable action. */ badSituation(do(moveToTable(X),S)) :- not goodTower(X,do(moveToTable(X),S)), existsActionThatCreatesGoodTower(S). existsActionThatCreatesGoodTower(S) :- (A = move(Y,X) ; A = moveToTable(Y)), poss(A,S), goodTower(Y,do(A,S)). % Canonical ordering of good-tower producing actions. badSituation(do(move(X1,Y1),do(move(X2,Y2),S))) :- X1 @< X2, poss(move(X1,Y1),S), poss(move(X2,Y2),do(move(X1,Y1),S)). badSituation(do(move(X1,Y1),do(moveToTable(X2),S))) :- X1 @< X2, poss(move(X1,Y1),S), poss(moveToTable(X2),do(move(X1,Y1),S)), goodTower(X2,do(moveToTable(X2),S)). badSituation(do(moveToTable(X1),do(move(X2,Y2),S))) :- X1 @< X2, poss(moveToTable(X1),S), poss(move(X2,Y2),do(moveToTable(X1),S)), goodTower(X1,do(moveToTable(X1),S)). badSituation(do(moveToTable(X1),do(moveToTable(X2),S))) :- X1 @< X2, poss(moveToTable(X1),S), poss(moveToTable(X2),do(moveToTable(X1),S)), goodTower(X1,do(moveToTable(X1),S)), goodTower(X2,do(moveToTable(X2),S)).