tags:

views:

100

answers:

3

So, let's say I have the following in a Prolog database:

person(john).
person(mary).
happy(john).

It is clear to that if I want to list all people, I can type:

person(X).

But, what if I want to find all the things that are true about john? I cannot do:

X(john).

But the effect I would like is to be able to put in "john" and get back "person" and "happy".

There is clearly another way I could store my information:

is(person, john).
is(person, mary).
is(happy, john).

And then, I can do:

is(X, john).

But I lose some expressiveness here. I really would like to be able to do something like:

X(john).

Any ideas?

Thanks!

A: 

Hm, from my experience, that's not the typical use case of Prolog. If you want to enumerate all "facts" about John, you would first have to define them as terms, and encode their arity. Then you can use call/N and go down the rabbit hole another notch (from memory with the help of GNU Prolog):

relation(1,person).
relation(2,married).
person(john).
married(john,mary).

? relation(1,X), call(X,john).

X = person

| ?- relation(2,X),call(X,john,Y).

X = married
Y = mary

Note that using call has many interesting issues and potential for runtime errors.

ShiDoiSi
Interesting. Thanks. I totally get that this is not the typical use case for Prolog -- but surely there must be some way to do what I am asking, right? It's a very important piece of information that is coded in the database, there must be a way to query it -- "What is true about X?"
Mike
How could Prolog possibly answer that question,even syntactically?There's no way that Prolog could sensibly put together the information from X(john) and married(john,..).Even from your database-example, you can feel that the facts would be along the lines of true(married(john,mary)) and true(person(john)),an almost identical encoding to the one I gave.Maybe with some other non-standard feature,you could ask: ? true(X), containsJohn(X), recursively dissecting X. But I'm not aware of a way to construct this "contains". Then there could indeed be a syntactical answer like "X=married(john,mary)".
ShiDoiSi
A: 

This is an approximation:

all_predicates(Term) :- 
  current_predicate(_, Pred), %% match Pred to any currently defined predicate
  \+ predicate_property(Pred, built_in), %% filter out the built-in predicates
  functor(Pred, Name, 1), %% check that Pred has 1 argument and match Name to its name
  Goal =.. [Name, Term], %% construct the goal Name(Term)
  call(Goal). %% Note that if Pred has side effects, they will happen.
Alexey Romanov
+2  A: 
sharky