2015-06-20 1 views
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 - это код, который пытается распечатать все эти факты. Как я могу подойти к этому? любая помощь будет замечательной! Спасибо.

ответ

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

В идеале вы бы хотели использовать 'bagof/3' или' setof/3' вместо 'findall' (поскольку они не работают, если нет решений, и не топтать точки выбора так, как это делает' findall'). –

+0

@Boris Вы правы. Моей главной целью было четко разделить * обработку данных * и * пользовательский интерфейс *. – dlask

+1

Благодарим за помощь! оно работает. @dlask – drunktiger

2

Из главы 11 в "The Craft of Prolog" Ричард О'Киф, немного упрощенный/переработан, чтобы сохранить нажатия клавиш:

 
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.

+0

Спасибо! @Boris – drunktiger

0

items_inroom/1 предикат всегда печатает первое вхождение Item по всем фактам isAt/2. Вам нужно перебрать все факты isAt/2 используйте metapredicate setof/3, bagog/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 
+0

Спасибо! @Yasel – drunktiger

 Смежные вопросы

  • Нет связанных вопросов^_^