How to get a list of objects in Prolog
I was resolving some prolog exercises when I fond myself with some difficulties resolving the following one: Consider you have this fact base about object:
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, j开发者_Python百科ar).
type(obj5, rattle).
weight(obj1, 10.5).
weight(obj2, 1.5).
weight(obj3, 1.6).
weight(obj4, 0.5).
weight(obj5, 1.8).
Now the idea is to make the predicate object_description(List) where List is the joining of each object with it's caracteristics, something like:
([obj1-wood-table-10.5, obj2-wood-chair-1.5, …, obj5-iron-rattle-1.8] )
I tried using bagof and findall but couldn't find the right answer.
Thx in advance
?- 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].
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
I've changed the input format. It's a little easier to search now. I hope it's OK like this.
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).
Given this input format you can now map it to a list (of lists) e.g. like this:
object_description(List) :-
findall(Id-TmpList, bagof(Type-Value, obj(Id, Type, Value), TmpList), List).
This doesn't produce the exact output format that you have in the question, but does give something similar (and maybe easier to process further).
Usage:
?- 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, ... - ...]].
精彩评论