Understanding reification - “What relationships hold between x and y?"

Combining aspects of both Paul's and Carlo's answers, another possible solution is to introduce a meta-relation predicate. For example:

relation(isa/2).
relation(ako/2).
relation(have_mass/1).
...

This avoids loosing the benefit of first-argument indexing for some of the queries using the original database because of the reification of relations. It also avoids, in Carlo's solution, the call to current_predicate/2 picking up e.g. auxiliary predicates that should not be considered.

With the definition above of the relation/2 predicate, we can write:

relation(Relation, Entity1, Entity2) :-
    relation(Relation/2),
    call(Relation, Entity1, Entity2).

relation(Relation, Entity) :-
    relation(Relation/1),
    call(Relation, Entity).

and then query:

?- relation(Relation, 'Ford', 'Companies').
Relation = isa.

Not sure this answer is what the book intended... I've read it many years ago, italian translated, and don't remember the question.

In SWI-Prolog, modules play an important role, so I would go with:

:- module(so_relationships, [which_rel/3]).

isa('Ole Black', 'Mustangs').
isa('Lizzy', 'Automobiles').
isa('Ford','Companies').
isa('GM','Companies').
isa('1968','Dates').

ako('Model T', 'Automobiles').
ako('Mustangs', 'Automobiles').
ako('Companies', 'Legal Persons').
ako('Humans', 'Legal Persons').
ako('Humans', 'Physical Objects').
ako('Automobiles', 'Physical Objects').
ako('Legal Persons', 'Universal').
ako('Dates', 'Universal').
ako('Physical Objects', 'Universal').

have_mass('Physical Objects').
self_propelled('Automobiles').

company(X) :- isa(X,'Companies').
legal_persons(X) :- ako(X,'Legal Persons').

which_rel(A,B,R) :-
    current_predicate(so_relationships:R/2),
    C=..[R,A,B],
    %catch(call(C),E,(writeln(E),fail)).
    call(C).

Note the (commented out) catch/3. Was required before qualification of the predicate indicator with the module name.

?- which_rel('Ford','Companies',R).
R = isa ;
false.

I'd like to add a little bit of background to the previous answers (which are very helpful).

As far as I can tell, there's no generally accepted defintion for reification in Prolog. One could say that the relationships in your original code are already partly reified. Examples:

isa('Ford', 'Companies').
% ...is a reification of...
company('Ford').

ako('Companies', 'Legal Persons').
% ...is a reification of...
legal_person(X) :- company(X).

have_mass('Physical Objects').
% ...is a reification of...
has_mass(X) :- physical_object(X).

self_propelled('Automobiles').
% ...is a reification of...
self_propelled(X) :- automobile(X).

See the Reification section in Notes on Semantic Nets and Frames by Matthew Huntbach for details.

Tags:

Prolog