1

我被这个问题困住了......

isAt(keys, room3).
isAt(book, room3).
isAt(keys, room6).
isAt(keys, room4).

目前,room3 有钥匙和书。我想打印钥匙和书。我试过这段代码,显然只打印了一个。(只是键)

look :- isIn(Location),
  write('You are in '),
  write(Location),
  nl,
  items_inroom(Location),
  nl.


items_inroom(Location) :-
    isIn(Location),
    isAt(Item, Location),
    write('Available Item(s):'), 
    write(Item),
    nl.

items_inroom(_) :-
    write('Available Item(s): None'),
    nl. 

items_inroom 是试图打印所有这些事实的代码。我该如何处理?任何帮助都会很棒!谢谢你。

4

3 回答 3

2

从 Richard O'Keefe 的“The Craft of Prolog”中的第 11 章,稍微简化/重构以节省击键:

print_item_report(位置):-
    ( setof(Item, isAt(Item, Location), Items)
    -> format("~w:~n 中可用的项目", [Location]),
        forall(成员(我,项目),
               格式(“~w~n”,[I]))
        % print_item_report_footer
    ; format("~w~n 中没有项目", [Location])
    )。

% ETC

如果format由于某种原因没有,您仍然可以使用write. 如果你没有forall,那么这个:

forall(Condition, Action)

定义为

\+ (Condition, \+ Action )

所以你可以改用它。有关详细信息,请参阅SWI-Prologforall/2文档

于 2015-06-22T12:06:52.873 回答
0

找到所有项目并显示它们。

items_inroom(Location) :-
    write('Available Item(s):'),
    findall(Item, isAt(Item, Location), Items),
    show_items(Items).

show_items([]) :-
    write('None'), !.

show_items(Items) :- 
    write(Items).

实际上,您可以show_items(Items)以任何您想要的方式实现。

于 2015-06-20T04:41:17.597 回答
0

items_inroom/1Item谓词将始终打印所有事实的第一次出现isAt/2。您需要遍历所有事实isAt/2,使用元谓词setof/3bagog/3或者findall/3,我会setof/3像@Boris 那样推荐,或者构建自己的 bucle(也许不是最好的主意,但它是一个选项):

show_items(Location):- isAt(Item, Location),   % Condition
                     write(Item), nl,          % Process result
                     fail.                     % force backtracking to evaluate condition and find a new result
show_items(_).                                 % return true when all options have been evaluated
于 2015-06-22T15:35:20.473 回答