Определение предиката is_a в прологе? - PullRequest
3 голосов
/ 15 января 2010

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

Предикат is_a(X, Y) должен возвращать true, если 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 ]

5 голосов
/ 16 января 2010

Один из способов избежать бесконечного цикла - добавить предикат, который показывает «прямое» наследование (без транзитивности), а именно 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

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

2 голосов
/ 16 января 2010

Что-то вроде

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

...