Определение предиката 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, который изо всех сил старался сохранить его как ваш оригинальный код.