如何打印所有的事实?(How to print all the facts?)

2019-10-23 10:33发布

我坚持了这个问题...

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是试图打印所有这些事实的代码。 我该如何处理这个? 任何帮助将是巨大的! 谢谢。

Answer 1:

查找所有项目,并显示它们。

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)在任何你想要的方式。



Answer 2:

从第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 )

所以你可以使用来代替。 见的SWI-Prolog的forall/2文件的详细信息。



Answer 3:

items_inroom/1谓词将始终打印第一次出现的Item上的所有事实isAt/2 。 您需要遍历所有的事实isAt/2 ,使用metapredicate setof/3bagog/3findall/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


文章来源: How to print all the facts?