Простая игра автозаправка в Прологе - PullRequest
0 голосов
/ 05 января 2020

Мне нужно составить программу в Прологе, где парень добирается до заправки, получает газировку и газету и возвращается к своей машине, результат должен выглядеть примерно так:

?- go. 
>> goto(gas_station). 

You are in the gas_station.
>> goto(car). 

You can't get there from here. 

>> open(car_door). 

>> open(gas_station_door). 

>> take(soda). 

You now have a soda. 

>> goto(car). 

You are in the car 

Thanks for getting the newspaper.

Это это то, что я сделал до сих пор:

place(car).
place(gas_station).
item(player , soda).
item(player , newspaper).
at(soda , gas_station).
at(newspaper , gas_station).

at(player , gas_station) :- door(car_door , open),
                door(gas_station_door, open), nl.

at(player , gas_station) :-
    write('Can't get there'), nl.


open(X) :-
    assert(door(X , open).

goto(X) :-
    at(player , X),
    retract(at(player , X),
    write('You are in the gas station.'),
    nl.

take(X) :-
    item(player , X),
    write('You now have a soda and a newspaper'),
    nl.

Я новичок в Прологе, я просто хочу знать, является ли то, что я до сих пор сделал, несколько правильно, если я на правильном пути, и как продолжить с здесь, потому что я стек, я не уверен, работает ли он так, как он должен или как вернуть парня в машину, я был бы признателен за любую помощь, спасибо.

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Я понял это благодаря опубликованной паучьей программе, и вот что я сделал:

:- dynamic at/2, i_am_at/1.
:- retractall(at(_, _)), retractall(i_am_at(_)).


i_am_at(car).

go_to_gas_station :- goto(gas_station).
go_to_car :- goto(car).
open_car_door :- open(car_door).
open_gas_station_door :- open(gas_station_door).
take_soda :- take(soda).
take_newspaper :- take(newspaper).

path(car, gas_station, gas_station) :- at(car_door, open),
                       at(gas_station_door, open).

path(car, gas_station, gas_station) :-
    write('Cant get there! Open the doors first.'), nl,
    !, fail.

path(gas_station, car, car) :- at(soda, in_hand),
                   at(newspaper, in_hand),
                   i_am_at(gas_station),
                   write('Thanks for playing.').

path(gas_station, car, car) :- 
    write('Did you forget something?'), nl,
    !, fail.


open(X) :-
    at(X, open),
    write('Door is already open!'),
    nl, !.

open(X) :-
    assert(at(X, open)),
    write('Door is now open.'),
    nl, !.

goto(Direction) :-
    i_am_at(Here),
    path(Here, Direction, There),
    write('You are now at '), write(Direction),
    retract(i_am_at(Here)),
    assert(i_am_at(There)), !.

take(X) :-
    at(X, in_hand),
    write('You already have it!'),
    nl, !.

take(X) :-
    assert(at(X, in_hand)),
    write('You now have '), write(X),
    nl, !.

Моя единственная проблема в том, что, как и сейчас, вы можете взять газировку и газету. независимо от того, где вы находитесь, вы сможете принимать их только тогда, когда находитесь на gas_station, если кто-то может мне помочь с этим, было бы неплохо, кроме этого спасибо за помощь.

0 голосов
/ 05 января 2020

Хорошо выглядит. Общая форма каждой «команды» (на самом деле, запрос Пролога, выданный в командной строке):

% precondition-dependent action:

commandX(Arg) :- check_precondition_for_commandX, !,
                 % past the "!" we are committed to the action
                 update_database_with_assert_and_retract_to_reflect_new_state,
                 print_out_some_message.

% maybe the effects of the action depend on another set of preconditions
% for example, going "north" may have different effects depending on
% current position

commandX(Arg) :- check_other_precondition_for_commandX, !,
                 % past the "!" we are committed to the action
                 update_database_with_assert_and_retract_to_reflect_new_state,
                 print_out_some_other_message.

% catch the case where preconditions are not fulfilled:

commandX(Arg) :- print_out_something_about_you_cant_do_that.

Возможно, запустите этот пример, найденный на GitHub: « spider.pl » для почувствовать, что происходит.

Включите tracer tracer, чтобы увидеть, что вызывается.

[debug]  ?- n.
Go into that dark cave without a light?  Are you crazy?
You can't go that way.
true.

[debug]  ?- trace.
true.

[trace]  ?- n.
   Call: (10) n ? creep
   Call: (11) go(n) ? creep
   Call: (12) i_am_at(_7492) ? creep
   Exit: (12) i_am_at(meadow) ? creep
   Call: (12) path(meadow, n, _7496) ? creep
   Call: (13) at(flashlight, in_hand) ? creep
   Fail: (13) at(flashlight, in_hand) ? creep
   Redo: (12) path(meadow, n, _7496) ? creep
   Call: (13) write('Go into that dark cave without a light?  Are you crazy?') ? creep
Go into that dark cave without a light?  Are you crazy?
   Exit: (13) write('Go into that dark cave without a light?  Are you crazy?') ? creep
   Call: (13) nl ? creep

   Exit: (13) nl ? creep
   Call: (13) fail ? creep
   Fail: (13) fail ? creep
   Fail: (12) path(meadow, n, _7496) ? creep
   Redo: (11) go(n) ? creep
   Call: (12) write('You can\'t go that way.') ? creep
You can't go that way.
   Exit: (12) write('You can\'t go that way.') ? creep
   Exit: (11) go(n) ? creep
   Exit: (10) n ? creep
true.

Не знаете, как это работает? Вот описание трассировки для ALS Prolog: Использование четырехпортового отладчика

...