2010-01-15 4 views
3

J'essaie de définir le prédicat d'héritage-vérification is_a/2 dans Prolog, mais jusqu'à présent, tous mes essais ont échoué.Définition d'un prédicat is_a dans prolog?

Le prédicat is_a(X, Y) doit retourner vrai lorsque Y est une superclasse de X. Par exemple:

object(bare). 
object(mammal). 
object(animal). 
object(bird). 
is_a(bare, mammal). 
is_a(mammal, animal). 
is_a(bird, animal). 
is_a(X, Y):- <definition goes here>. 

La définition devrait aller de telle sorte que la requête suivante retourne vrai:

?- is_a(bare, animal). 
true. 

J'ai essayé pour le définir le évident façon, mais je suis resté coincé dans des boucles infinies:

is_a(X, Y):- X\==Y, object(X), object(Y), object(Z), is_a(X, Z), is_a(Z, Y). 

Des suggestions?

Répondre

5

Une façon d'éviter la boucle infinie est d'ajouter un prédicat, qui montre l'héritage "direct" (pas de transitif), à savoir direct/2. Ensuite, vous pouvez écrire quelque chose comme ceci:

object(bare). 
object(mammal). 
object(animal). 
object(bird). 

direct(bare, mammal). 
direct(mammal, animal). 
direct(bird, animal). 

isa(X, Y) :- object(X), object(Y), direct(X, Y). 
isa(X, Y) :- object(X), object(Y), object(Z), direct(X, Z), isa(Z, Y). 

Ensuite, vous obtenez:

?- findall(X, isa(X, animal), L). 
    L = [mammal,bird,bare] ? ; 
    no 

Je ne suis pas sûr que ce soit exactement ce que vous demandez bien.

+0

Exactement ce que je cherche :) merci beaucoup, 3lectrologos –

2

Quelque chose comme

is_a(X, X). 
is_a(X, Y) :- X \== Y, is_a_1(X, Z), is_a(Z, Y). 
is_a_1(bear, mammal). 
is_a_1(mammal, animal). 
is_a_1(bird, animal). 

Edit: idée même que la réponse de electrologos3, qui a essayé plus difficile de le garder comme votre code d'origine.