Определение предиката is_a в прологе?

Я пытаюсь определить предикат проверки наследования is_a/2 в Прологе, но пока все мои испытания провалились.

is_a(X, Y) Предикат должен возвращать истину всякий раз, когда Y является суперклассом X. Например:

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

Определение должно идти так, чтобы следующий запрос вернул true:

?- is_a(bare, animal).
true.

Я попытался определить это очевидным образом, но я застрял в бесконечных циклах:

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

Какие-либо предложения?

2 ответа

Решение

Одним из способов избежать бесконечного цикла является добавление предиката, который показывает "прямое" наследование (без транзитивности), а именно direct/2, Тогда вы могли бы написать что-то вроде этого:

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

Тогда вы получите:

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

Я не уверен, что это именно то, что вы просите, хотя.

Что-то вроде

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

Редактировать: та же идея, что и в ответе electrologos3, который изо всех сил старался сохранить его как ваш оригинальный код.

Другие вопросы по тегам