2015-10-30 29 views
0

我需要一些非常基本的幫助如何解決這個問題。我有一個房間計劃器,給定一個開始狀態和結束狀態,它使用遞歸來解決這個問題。但是,我想解決這兩個狀態(又名房間)。我決定設置標誌將是我最好的選擇,因爲每個房間的狀態都在1號房間或2號房間。但是我不知道如何實現這一點。任何可以推動我朝着正確的方向發展?兩個房間的計劃器塊世界序言

只是爲了澄清,新國家將代替ontable(X)(ontable(X),房間1)

:- 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)]). 
+0

我會添加一個房間標識符ontable – CapelliC

+0

我會如何溝通兩個房間?所以如果在房間1中,那麼前提條件是將手臂移動到房間2等等? (持有(X))等。 –

+0

我猜handempty不取決於房間,以及舉行等等這些都是球員的屬性。你應該添加一個current_room(X)給玩家道具,雖然 – CapelliC

回答

0

所以我解決它通過使用標誌基本上是這樣。因此,對於每個移動謂詞,我基本上都會添加room1和room2標誌。如果他們是真的,那麼它會採取行動。因此,例如room1中的ontable(X),然後刪除ontable並在room1中添加保留(X)。我還添加了兩個謂詞在房間之間移動。最大的障礙是從程序邏輯轉向狀態邏輯。所以如果handempty在room1,那麼它只能移動到room2! @CapelliC感謝您的建議