【问题标题】:Simple car-gas station game in PrologProlog中的简单汽车加油站游戏
【发布时间】:2020-01-05 18:57:16
【问题描述】:

我需要在 Prolog 中编写一个程序,让一个人去加油站,拿一杯苏打水和一份报纸,然后回到他的车上,结果应该是这样的:

?- 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.

我是 Prolog 的新手,我只想知道到目前为止我所做的是否正确,我是否在正确的轨道上,以及如何从这里继续,因为我是堆栈,我不确定它是否有效应该怎么做或如何让那个人回到车上,我会很感激任何帮助,谢谢。

【问题讨论】:

  • David Matuszek的课程吗?看看Example on Github 公平吗?该示例不使用读取循环,它只是修改事实数据库,用户直接输入操作作为查询news 等。非常非单调的逻辑。这是一种方法。
  • assertretract 语句肯定缺少一些括号。
  • 也许您正在寻找planner 解决方案。

标签: prolog adventure


【解决方案1】:

目前看起来不错。每个“命令”(实际上是在命令行上发出的 Prolog 查询)的一般形式是:

% 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 跟踪器以查看正在调用的内容。

[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 跟踪的描述:Using the Four Port Debugger

【讨论】:

    【解决方案2】:

    感谢发布的蜘蛛程序,我发现了这一点,这就是我所做的:

    :- 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, !.
    

    我唯一的问题是,现在,无论您身在何处,都可以带汽水和报纸,只有在加油站时才能带走它们,如果有人可以帮助我的话会很好,除此之外感谢您的帮助。

    【讨论】:

      猜你喜欢
      • 2011-10-29
      • 1970-01-01
      • 1970-01-01
      • 2012-10-07
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      • 1970-01-01
      相关资源
      最近更新 更多