Pergunta

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!

Foi útil?

Solução

Parameterizing a query over predicates (as in finding ∀x over x(...)) is not usually possible natively in PROLOG, as this sort of thing is a second- (or, higher)-order logic operation, whereas PROLOG is based on first-order logic.

There are, however, descriptions of how implementations of higher-order logic functions in PROLOG are possible, at least to a limited extent - there are real uses for such functionality. See The Art Of Prolog, Chapter 16, and Higher-order logic programming in Prolog by Lee Naish.

Outras dicas

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.

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.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top