2013-11-10 2 views
1

Я хочу создать правило, которое использует наследование. Например, вот известный пример, который используется во многих книгах пролога, описывающих наследование.Как я могу переопределить свойство в отношениях Наследование в PROLOG?

a busy cat http://staff.unak.is/not/tony/teaching/ai/lectures/09bSemanticNet/lab18/birdSemanticNet.gif

и вот факты для этих отношений:

%Bird 
%animal's childs 
isa(bird, animal). 
isa(fish, animal). 

%bird's childs 
isa(ostrich, bird). 
isa(penguin, bird). 
isa(canary, bird). 
isa(robin, bird). 

%penguin's childs 
isa(opus, penguin). 

%canary's childs 
isa(tweety, canary). 

%animal's property 
hasprop(animal, covering, skin). 

%bird's property 
hasprop(bird, travel, fly). 
hasprop(bird, covering, feathers). 

%fish's property 
hasprop(fish, travel, swim). 

%ostrich's property 
hasprop(ostrich, travel, walk). 

%penguin's property 
hasprop(penguin, travel, walk). 
hasprop(penguin, color, brown). 

%canary's property 
hasprop(canary, color, yellow). 
hasprop(canary, sound, sing). 

%robin's property 
hasprop(robin, color, red). 
hasprop(robin, sound, sing). 

%tweety's property 
hasprop(tweety, color, white). 

%rules 
hasproperty(Object, Property, Value) :- hasprop(Object, Property, Value),!. 

hasproperty(Object, Property, Value) :- isa(Object, Parent), 
             hasproperty(Parent, Property, Value). 

В этой сети, когда я запрашиваю заявление как HasProperty (пингвин, X, Y), я мог бы только получить один результат (и я знаю, что это из-за оператора cut.). То, что я хочу, это результат, который нравится:

?- hasproperty(penguin, X, Y). 

X = travel, 
Y = walk. 

X = color, 
Y = brown. 

X = covering, 
Y = feathers. 

В результате классов ниже уровня свойство, путешествие и покрытие переопределяют классы верхнего уровня. Но я не имею ни малейшего представления об этих проблемах. Если у вас есть какое-либо решение по этому поводу, сообщите мне.

ответ

2

Возможный подход будет проверять сразу же свойство объекта в вашем втором hasproperty/3 пункта:

hasproperty(Object, Property, Value) :- 
    hasprop(Object, Property, Value). 

hasproperty(Object, Property, Value) :- 
    isa(Object, Parent), 
    hasproperty(Parent, Property, Value), 
    \+ hasprop(Object, Property, _). % Let object property override 
+0

О, я понял, и это работает без проблем. действительно оценил :) –

2

Альтернативное решением является просто представлять иерархию с использованием объектов Logtalk и объявлением и определением объектов предикатов для представления свойств , Вы можете запустить Logtalk с помощью SWI-Prolog в качестве компилятора Prolog для бэкэнда или любого другого из поддерживаемых компиляторов Prolog. Учитывая количество узлов в иерархии, я буду иллюстрировать только некоторые из них:

:- object(animal). 

    :- public(covering/1). 
    covering(skin). % default covering 

    :- public(travel/1). 

:- end_object. 


:- object(fish, extends(animal)). 

    travel(swim). 

:- end_object. 


:- object(bird, extends(animal)). 

    covering(feathers). 
    travel(fly). 

:- end_object. 

После определения всех необходимых объектов и предикаты, тривиально, чтобы задать конкретный объект для их свойств или их значений свойств. Например:

?- bird::current_predicate(Property). 
Property = covering/1 ; 
Property = travel 
true. 

?- bird::travel(Travel). 
T = fly 
true. 

Наследование, включая переопределение, предоставляется бесплатно. Эквивалент hasproperty/3 предиката будет что-то вроде:

?- current_object(Object), Object::current_predicate(Functor/Arity), functor(Property, Functor, Arity), Object::Property. 

Иерархии теперь хорошо представлена, легко изменить, и вы даже можете использовать инструмент диаграммы Logtalk, чтобы получить PDF с ним напоминающим своей фотографией выше.

Смежные вопросы