#prolog #semantic-web #swi-prolog
#пролог #semantic-web #swi-prolog
Вопрос:
У меня есть семантическая сеть со следующей иерархией:
Person: has body = true
Man: is a Person, height = 170
Sport Star: is a Man, height = 190
Затем я хочу создать их экземпляры, такие как:
Mark: is a Sport Star
Однако, когда я вызываю, например, height(Mark, X)
я получаю X = 170
, и мне нужно нажать ;
, чтобы получить X = 190
. Есть ли способ просто получить 190
сразу?
Комментарии:
1. Пожалуйста, покажите нам свой код и / или запросы!
Ответ №1:
SWI-Prolog, который, как вы указали, вы используете, имеет обширную поддержку технологий Semantic Web. Но если ваша семантическая сеть состоит только из отношений иерархии is-a, вы также можете легко выразить их с помощью Logtalk, который вы можете запускать с SWI-Prolog и большинством систем Prolog, что делает его широко переносимым:
% Person: has body = true
:- object(person).
:- public(has/1).
has(body).
:- end_object.
% Man: is a Person, default height = 170
:- object(man, extends(person)).
:- public(height/1).
height(170).
:- end_object.
% Sport Star: is a Man, default height = 190
:- object(sport_star, extends(man)).
% override inherited height
height(190).
:- end_object.
% Mark: is a Sport Star
:- object(mark, extends(sport_star)).
:- end_object.
% Spencer: is another Sport Star, but slim
:- object(spencer, extends(sport_star)).
% override inherited height
height(165).
:- end_object.
Это решение использует иерархию прототипов. Примеры вызовов (детерминированные; без ложных точек выбора):
?- mark::height(Height).
Height = 190.
?- mark::has(What).
What = body.
?- spencer::height(Height).
Height = 165.
Вы можете создать столько прототипов, сколько вам нужно, либо определенных в исходном файле, либо созданных динамически во время выполнения. Например.
?- create_object(alan, [extends(man)], [], []).
true.
?- alan::height(Height).
Height = 170.
Также возможно использовать классы вместо прототипов, если вам нужно различать абстракции и конкретные примеры этих абстракций.
Ответ №2:
Ответ Пауло Моуры является хорошим примером возможностей расширений и библиотек Prolog. Если вы создаете реальное приложение, то лучше всего было бы использовать что-то подобное. Однако, на случай, если вы изучаете Prolog и хотите знать, как это работает, вот дополнительный чисто прологовский ответ.
Поведение, которое вы наблюдали, согласуется с вашей базой знаний, что допускает две возможные интерпретации: Марк — человек, и поэтому его рост равен 170, или Марк — спортсмен, и поэтому его рост равен 195. Оба являются допустимыми производными, которые поддерживаются базой знаний, поэтому Prolog возвращает каждое из них по очереди.
Вы можете наложить дополнительные ограничения на правила, чтобы остановить вывод, как только встречается первый факт. Затем правило формулируется как «высота X является либо базовым фактом для объектов типа X, либо, если базового факта нет, следуйте соотношению isa и повторите попытку». Для этого базовым фактам необходимо присвоить другое имя, отличное от правила. Часть, которой нет, может быть представлена оператором отрицания
.
Код:
% isa: general facts
isa(father,man).
isa(man,person).
% isa: specific facts
isa(mark,sportsman).
% height: general facts
height_base(person,170).
height_base(sportsman,195).
% height: rules
height(X,H) :- height_base(X,H).
height(X,H) :- height_base(X,_), isa(X,T), height(T,H).
Запросы:
?- height(man,X).
X = 170 ;
false.
?- height(mark,X).
X = 195 ;
false.
?- height(sportsman,X).
X = 195 ;
false.
?- height(person,X).
X = 170 ;
false.