Двухкомнатный планировщик Blocks world Prolog

Мне нужна некоторая базовая помощь о том, как подойти к этой проблеме. У меня есть планировщик одной комнаты, который, учитывая начальное и конечное состояние, решает эту проблему с помощью рекурсии. Тем не менее, я хочу решить эту проблему для двух государств (или комнат). Я решил, что установка флагов будет моей лучшей ставкой, так как каждое состояние комнат находится либо в комнате1, либо в комнате2. Однако я не знаю, как это реализовать. Кто-нибудь может подтолкнуть меня в правильном направлении?

Просто чтобы уточнить, новые состояния будут (ontable(X), room1) вместо 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)]).

1 ответ

Решение

Так что я решил это, используя флаги в основном. Поэтому для каждого предиката хода я в основном добавляю флаг room1 и room2. Если они верны, то это делает действие. Так, например, ontable(X) в комнате1, затем del ontable и добавить удержание (X) в комнате1. Я также добавляю два предиката для перемещения между комнатами. Самым большим препятствием был переход от процедурной логики к государственной логике. Так что, если handempty находится в комнате1, то он может двигаться только в комнату2! @CapelliC спасибо за совет

Другие вопросы по тегам