out_sider
out_sider

Reputation: 11

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, jar). 
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

Upvotes: 1

Views: 740

Answers (3)

XLogic
XLogic

Reputation: 11

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

Upvotes: 1

Volodymyr Gubarkov
Volodymyr Gubarkov

Reputation: 2183

 ?- 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].

Upvotes: 1

Kaarel
Kaarel

Reputation: 10672

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, ... - ...]].

Upvotes: 0

Related Questions