2013-10-19 40 views
0

我尝试创建序言一个简单的程序,但我有一个问题(?):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

当你说“当我运行我的代码时......”究竟是什么意思?你输入了什么?我玩了你展示的代码,它的行为和我所期望的一样。如果你输入'take(左轮手枪)',你需要记住有多个“解决方案”。第一个会写“你拿起左轮手枪”,然后第二个(如果你用';'来要求)会修改数据。 – lurker

+0

当我运行的代码,左轮手枪正在从'Place'收回,但我怎么能阻止消息当用户再次使用'拿(左轮)''查询您拿起被再次显示revolver.' ? – Shevliaskovic

+0

取(X): - i_am_holding(X), 写( '已经特殊照顾抱着它!'), NL。 我明白了。无论如何感谢 – Shevliaskovic

回答

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。那里有很多很棒的点子!

+0

我对序言不太熟悉,所以我不知道'〜'做了什么。我几乎不了解你发布的内容:P – Shevliaskovic

+0

@NickShev'〜'被'format/2'用来引入格式化代码。如果没有'format/2',这并不意味着什么,所以如果你没有使用SWI,那对你无能为力。什么特别让你困惑?我很乐意解释任何不清楚的东西。我的目的只是为了说明你可以采用这些代码的一些方向。 Prolog具有很多强大的功能,可能很难从更高级的一个级别了解代码中正在发生的事情。 –

+0

有没有地方可以谈论没有评论? – Shevliaskovic