简体   繁体   中英

Defining is_a predicate in prolog?

I'm trying to define the inheritance-check predicate is_a/2 in Prolog, but so far all my trials failed.

The is_a(X, Y) predicate should return true whenever Y is a superclass of X. For example:

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>.

The definition should go such that the following query will return true:

?- is_a(bare, animal).
true.

I tried to define it the obvious way, but I got stuck in infinite loops:

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

Any suggestions?

One way to avoid the infinite loop, is to add a predicate, which shows "direct" inheritance (no transitive), namely direct/2 . Then you could write something like this:

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).

Then you get:

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

I'm not sure this is exactly what you ask for though.

Something like

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: Same idea as electrologos3's answer, who tried harder to keep it like your original code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM