Как получить список объектов в Прологе

Я выполнил некоторые прологические упражнения, когда столкнулся с некоторыми трудностями, решив следующие: представьте, что у вас есть эта база фактов об объекте:

object(obj1). 
object(obj2). 
object(obj3). 
object(obj4). 
object(obj5). 
material(obj1,wood). 
material(obj2,wood). 
material(obj3, glass). 
material(obj4, glass). 
material(obj5, iron). 
type(obj1, able). 
type(obj2, chair). 
type(obj3, mesa). 
type(obj4, jar). 
type(obj5, rattle). 
weight(obj1, 10.5). 
weight(obj2, 1.5). 
weight(obj3, 1.6). 
weight(obj4, 0.5). 
weight(obj5, 1.8).  

Теперь идея состоит в том, чтобы сделать предикат object_description(List), где List - это соединение каждого объекта с его характеристиками, что-то вроде:

([obj1-wood-table-10.5, obj2-wood-chair-1.5, …, obj5-iron-rattle-1.8] ) 

Я попытался использовать bagof и findall, но не смог найти правильный ответ.

Спасибо заранее

3 ответа

classic style of prolog :

    member(_, []):-!,fail.
    member(X, [X| _]).
    member(X, [_|T]):- member(X,T).

    object_description(R):-
           get_all_objects([], R).

    get_all_objects(T, [H|R]):-
          get_object(H),
          not(member(H,T)),
          get_all_objects([H|T], R).
    get_all_objects([], []).

    get_object(Obj):-
          object(X),
          material(X,M),
          type(X, T),
          weight(X, W),
          concat(X, "-", R1),
          concat(R1, M, R2),
          concat(R2, "-", R3),
          concat(R3, T, R4),
          concat(R4, "-", R5),
          concat(R5, W, Obj).

% // concat(str1, str2, str3) if your compilator have'nt you must make it or use other %//analog, idea is  str1+str2=str3
 ?- findall(O-M-T-W,(object(O),material(O,M),type(O,T),weight(O,W)),Res).
Res = [obj1-wood-able-10.5, obj2-wood-chair-1.5, obj3-glass-mesa-1.6, obj4-glass-jar-0.5, obj5-iron-rattle-1.8].

Я изменил формат ввода. Это немного легче искать сейчас. Я надеюсь, что все в порядке, как это.

obj(obj1, material, wood).
obj(obj2, material, wood).
obj(obj3, material, glass).
obj(obj4, material, glass).
obj(obj5, material, iron).
obj(obj1, type, table).
obj(obj2, type, chair).
obj(obj3, type, mesa).
obj(obj4, type, jar).
obj(obj5, type, rattle).
obj(obj1, weight, 10.5).
obj(obj2, weight, 1.5).
obj(obj3, weight, 1.6).
obj(obj4, weight, 0.5).
obj(obj5, weight, 1.8).

Учитывая этот формат ввода, вы можете теперь сопоставить его со списком (списков), например, так:

object_description(List) :-
    findall(Id-TmpList, bagof(Type-Value, obj(Id, Type, Value), TmpList), List).

Это не дает точного выходного формата, который у вас есть в вопросе, но дает что-то похожее (и, возможно, проще обрабатывать дальше).

Использование:

?- object_description(List).
List = [obj1-[material-wood, type-table, weight-10.5],
        obj2-[material-wood, type-chair, weight-1.5],
        obj3-[material-glass, type-mesa, weight-1.6],
        obj4-[material-glass, type-jar, weight-0.5],
        obj5-[material-iron, type-rattle, ... - ...]].
Другие вопросы по тегам