0

I need some very basic help on how to approach this problem. I have a one room planner that, given a start state and end state, it solves this using recursion. However, I want to solve this for two states (aka rooms). I decided that setting flags would be my best bet since each state of the rooms is either in room1 or room2. However I do not know how to implement this. Any can push me in the right direction?

Just to clarify, the new states would be (ontable(X), room1) instead of ontable(X)

:- module( planner,
       [
           plan/4,change_state/3,conditions_met/2,member_state/2,
           move/3,go/2,test/0,test2/0
       ]).

:- [utils].

plan(State, Goal, _, Moves) :-  equal_set(State, Goal),
                write('moves are'), nl,
                reverse_print_stack(Moves).
plan(State, Goal, Been_list, Moves) :-
                move(Name, Preconditions, Actions),
                conditions_met(Preconditions, State),
                change_state(State, Actions, Child_state),
                not(member_state(Child_state, Been_list)),
                stack(Child_state, Been_list, New_been_list),
                stack(Name, Moves, New_moves),
            plan(Child_state, Goal, New_been_list, New_moves),!.

change_state(S, [], S).
change_state(S, [add(P)|T], S_new) :-   change_state(S, T, S2),
                    add_to_set(P, S2, S_new), !.
change_state(S, [del(P)|T], S_new) :-   change_state(S, T, S2),
                    remove_from_set(P, S2, S_new), !.
conditions_met(P, S) :- subset(P, S).

member_state(S, [H|_]) :-   equal_set(S, H).
member_state(S, [_|T]) :-   member_state(S, T).

/* move types */

move(pickup(X), [handempty, clear(X), on(X, Y)],
        [del(handempty), del(clear(X)), del(on(X, Y)),
                 add(clear(Y)), add(holding(X))]).

move(pickup(X), [handempty, clear(X), ontable(X)],
        [del(handempty), del(clear(X)), del(ontable(X)),
                 add(holding(X))]).

move(putdown(X), [holding(X)],
        [del(holding(X)), add(ontable(X)), add(clear(X)),
                  add(handempty)]).

move(stack(X, Y), [holding(X), clear(Y)],
        [del(holding(X)), del(clear(Y)), add(handempty), add(on(X, Y)),
                  add(clear(X))]).

move(goroom1, [handempty], []).
move(goroom1, [holding(X)], []).

move(goroom2, [handempty], []).
move(goroom2, [holding(X)], []).

/* run commands */

go(S, G) :- plan(S, G, [S], []).

test :- go([handempty, ontable(b), ontable(c), on(a, b), clear(c), clear(a)],
              [handempty, ontable(c), on(a,b), on(b, c), clear(a)]).

test2 :- go([handempty, ontable(b), ontable(c), on(a, b), clear(c), clear(a)],
              [handempty, ontable(a), ontable(b), on(c, b), clear(a), clear(c)]).
vmg
  • 4,176
  • 2
  • 20
  • 33
heyblackduck
  • 117
  • 13
  • I would add a room identifier to ontable – CapelliC Oct 30 '15 at 07:17
  • How would I communicate between both rooms? So if handempty is in room1, what would the preconditions be to move the arm to room2 and so forth? (holding(X)) etc. – heyblackduck Oct 30 '15 at 12:13
  • I guess handempty doesn't depends on room, as well as holding etc. those are properties of the player. You should add a current_room(X) to player props, though – CapelliC Oct 30 '15 at 12:50
  • that makes sense, but how would I know when to switch rooms based off these states. So suppose room 2 just had ontable(x, room2) and current_room(room2) and I want to get block y from ontable(y, room1). How would i represent this in the move predicate. I am thinking move(goroom1, [CONDITION] ontable(y, room1), current_room(room2), [ACTION] current_room(room1), (handempty, room1). – heyblackduck Oct 30 '15 at 13:29
  • seems rather obvious... of course, it depends on details... – CapelliC Oct 30 '15 at 13:32

1 Answers1

0

So I solved it by using flags basically. So for each move predicate I basically add a room1 and room2 flag. If they are true then it does the action. So for example ontable(X) in room1 then del ontable and add holding(X) in room1. I also add two predicates to move between rooms. The biggest hurdle was moving from procedural logic to state logic. So if handempty is in room1 then it can only move to room2! @CapelliC thank you for the advice

heyblackduck
  • 117
  • 13