如何打印所有事实?

时间:2015-06-20 02:23:16

标签: list printing prolog fact

我遇到了这个问题......

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是试图打印所有这些事实的代码。 我怎么处理这个? 任何帮助都会很棒!谢谢。

3 个答案:

答案 0 :(得分:2)

来自Richard O'Keefe的"The Craft of Prolog"中的第11章,有点简化/重构以节省击键次数:

print_item_report(Location) :-
    (   setof(Item, isAt(Item, Location), Items)
    ->  format("Items available in ~w:~n", [Location]),
        forall(member(I, Items),
               format("~w~n", [I]))
        % print_item_report_footer
    ;   format("No items in ~w~n", [Location])
    ).

% etc

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

forall(Condition, Action)

定义为

\+ (Condition, \+ Action )

所以你可以改用它。有关详细信息,请参阅the SWI-Prolog forall/2 documentation

答案 1 :(得分: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)

答案 2 :(得分:0)

items_inroom/1谓词将始终在所有事实Item上打印isAt/2的第一次出现。您需要遍历所有事实isAt/2,使用元预测setof/3bagog/3findall/3,我会像@Boris那样推荐setof/3,或者构建你自己的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