Recherche inversée en Prolog? (Comment puis-je trouver tout ce qui est vrai sur X?)
-
28-09-2019 - |
Question
Alors, disons que je suit dans une base de données Prolog:
person(john).
person(mary).
happy(john).
Il est clair que si je veux la liste de tous les gens, je peux taper:
person(X).
Mais, si je veux trouver toutes les choses qui sont vraies au sujet de John? Je ne peux pas faire:
X(john).
Mais l'effet que je voudrais est de pouvoir mettre en « john » et de se remettre « personne » et « heureux ».
Il y a clairement une autre façon que je pouvais stocker mes informations:
is(person, john).
is(person, mary).
is(happy, john).
Et puis, je peux le faire:
is(X, john).
Mais je perds une expressivité ici. Je voudrais vraiment pouvoir faire quelque chose comme:
X(john).
Toutes les idées?
Merci!
La solution
Paramétrer une requête sur prédicats (comme dans la recherche sur ∀x
x(...)
) est généralement pas possible nativement en Prolog, comme ce genre de chose est un deuxième (ou ultérieure) opération logique -order, alors que PROLOG est basé sur la logique du premier ordre.
Il y a, cependant, une description de la façon dont les mises en œuvre des fonctions logiques d'ordre supérieur en Prolog sont possibles, au moins dans une certaine mesure - il y a des utilisations réelles pour cette fonctionnalité. Voir L'art de Prolog, Chapitre 16 et programmation logique d'ordre supérieur en Prolog par Lee Naish .
Autres conseils
Hm, de mon expérience, ce n'est pas l'utilisation typique cas de Prolog. Si vous voulez énumérer tous les « faits » au sujet de John, vous d'abord de les définir comme des termes et coder leur arité. Ensuite, vous pouvez utiliser call/N
et aller dans le trou de lapin d'un cran (de la mémoire avec l'aide de 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
Notez que l'utilisation call
a de nombreuses questions intéressantes et les possibilités d'erreurs d'exécution.
Ceci est une 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.