如何打印所有事实?
How to print all the facts?
我被这个问题困住了...
isAt(keys, room3).
isAt(book, room3).
isAt(keys, room6).
isAt(keys, room4).
目前,房间 3 有钥匙和书。
我想打印钥匙和书。
我试过这段代码,显然只打印了一个。 (只是键)
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 是试图打印所有这些事实的代码。
我该如何处理?
任何帮助都会很棒!谢谢。
找到所有项目并显示它们。
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)
。
来自 Richard O'Keefe "The Craft of Prolog" 的第 11 章,有点 simplified/refactored 以节省击键:
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。
items_inroom/1
谓词将始终在所有事实 isAt/2
上打印第一次出现的 Item
。您需要遍历所有事实 isAt/2
,使用元谓词 setof/3
, bagog/3
or findall/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
我被这个问题困住了...
isAt(keys, room3).
isAt(book, room3).
isAt(keys, room6).
isAt(keys, room4).
目前,房间 3 有钥匙和书。 我想打印钥匙和书。 我试过这段代码,显然只打印了一个。 (只是键)
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 是试图打印所有这些事实的代码。 我该如何处理? 任何帮助都会很棒!谢谢。
找到所有项目并显示它们。
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)
。
来自 Richard O'Keefe "The Craft of Prolog" 的第 11 章,有点 simplified/refactored 以节省击键:
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。
items_inroom/1
谓词将始终在所有事实 isAt/2
上打印第一次出现的 Item
。您需要遍历所有事实 isAt/2
,使用元谓词 setof/3
, bagog/3
or findall/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