Prolog断言/收回不起作用(?)

时间:2013-10-19 14:49:30

标签: dynamic prolog prolog-assert

我尝试在prolog中创建一个简单的程序,但我有一个问题:

:- dynamic at/2, i_am_holding/1, i_am_at/1.

/* some lines of code */

i_am_at(room1).

at(revolver, room1).

take(revolver) :- write('You picked up the revolver.'),nl.

take(X):- i_am_at(Place),
      assert(i_am_holding(X)),
      retract(at(X,Place)).

/* some lines of code */

我希望用户拿起左轮手枪,然后(左轮手枪)从他所在的地方收回,这样他就无法再拿起它了。

运行代码时,take(revolver)查询会运行,但take(X)不会运行。

1 个答案:

答案 0 :(得分:2)

马克是对的钱。您可能希望用以下内容替换整个代码:

:- dynamic at/2, holding/1.

at(player, room1).
at(revolver, room1).

take(X) :-
    at(player, Place),
    at(X, Place),
    !,
    format('You pick up the ~a.~n', [X]),
    retract(at(X,Place)),
    assert(holding(X)).

take(X) :-
    holding(X),
    !,
    format('You''re already holding the ~a!~n', [X]).

有很多有趣的方法可以让你更进一步。运算符is_at可能使代码更具可读性:

take(X) :-
  player is_at Place,
  X is_at Place,
  ...

你也可以通过一些很好的基于案例的推理来获取文章和其他正确的方法:

subject(X, Some_X) :- mass_noun(X), !, atom_concat('some ', X, Some_X).
subject(X, The_X)  :- atom_concat('the ', X, The_X).

mass_noun(water).

然后你可以将它们集成到输出例程中:

take(X) :- 
  ...
  subject(X, Subj),
  format('You take ~a.~n', [Subj]),
  ...

您可以使用DCG做一些有趣的事情来生成输出:

:- use_module(library(dcg/basics)).

success(take(X)) --> "You took ", subject(X).
subject(X) --> "the ", atom(X).

你可以用这样的一些戏剧作品来更加通用:

success_term(Command) --> { Command =.. CommandList }, success(CommandList).
success([Command, DirectObject]) --> 
  "You ", past_tense(Command), " ", subject(DirectObject), ".".

subject(Noun) --> "the ", atom(Noun).
past_tense(X) --> { past_tense(X, Y) }, atom(Y).

past_tense(take, took).
past_tense(X, Xed) :- atom_concat(X, 'ed', Xed).

然后像这样运行:phrase(success_term(take(revolver)), X), format('~s~n', [X]),你会得到You took the revolver.,这有点整洁。

这些文字冒险对代码来说很有趣。如果您还没有,我建议您浏览Amzi Prolog Nani Search tutorial。那里有很多很棒的想法!