tags:

views:

40

answers:

1

This is probably a very silly question (I just started learning Prolog a few hours ago), but is it possible to find all the clauses related to an atom? For example, assuming the following knowledge base:

cat(tom).
animal(X) :- cat(X).

, is there a way to obtain every possible information about tom (or at least all the facts that are explicitly stated in the base)? I understand that a query like this is not possible:

?- Pred(tom).

so I thought I could write a rule that would deduce the correct information:

meta(Object, Predicate) :-
    Goal =.. [Predicate, Object],
    call(Goal).

so that I could write queries such as

?- meta(tom, Predicate).

but this does not work because arguments to call are not sufficiently instantiated. So basically my question is: is this at all possible, or is Prolog not design to provide this kind of information? And if it is not possible, why?

+1  A: 

You can use the ISO predicate "current_predicate/1" to find out what you can call. Here is a sample program:

cat(tom).
animal(X) :- cat(X).

info(Arg,Info) :- current_predicate(PredName/1),
     Info =.. [PredName,Arg], call(Info).
all_info(Arg,L) :- findall(I,info(Arg,I),L).

You can use the program as follows (I am using SICStus Prolog btw):

| ?- info(tom,X).
X = animal(tom) ? ;
X = cat(tom) ? ;
no
| ?- all_info(tom,X).
X = [animal(tom),cat(tom)] ? 
yes

Generally, you can use

current_predicate
as follows:

| ?- current_predicate(X).
X = info/2 ? ;
X = animal/1 ? ;
X = cat/1 ? ;
X = all_info/2 ? ;
no
Michael
This is very interesting! However, I find it sad to have to test the parameter against all possible predicates in the KB, I assume there could be more efficient ways of achieving this if the feature was embedded in the language. Another issue I have with the solution you propose is that my Prolog engine (SWI-Prolog) includes in the result set of current_predicate/1 all the predefined predicates (such as atomic/1, functor/3 and so on), which eventually lead to a context error; do you have some advice on how I could prevent that? Nevertheless, thanks a lot for your insightful answer!
Luc Touraille
Regarding my previous comment, I just discovered predicate_property/2 which might help me solve the issue I described.
Luc Touraille