Уголок OWL

На этой страничке будут собираться интересные, простые но нетривиальные примеры использования OWL. Надеемся, что с вашей помощью этот Уголок быстро перерастет размеры одной страницы!

Я буду использовать Манчестерский синтаксис OWL (не потому, что я сам из Манчестера, а просто потому, что он самый короткий и читабельный). Первым нашим примером будет тот самый «дядя».

1) Класс «Дядя» (Uncle) — класс всех объектов, братья и сестры которых имеют своих детей. Реализация в OWL 2:

ObjectProperty: hasParent • hasBrother
SubPropertyOf: hasUncle
Class Uncle:
EquivalentTo: Person that (inverse hasUncle some Person)

Объяснение: здесь используется цепочка свойств (property chain) с вложенностью: сложное свойство hasParent hasBrother (цепочка двух свойств) являетс подсвойством hasUncle (это аналогично правилу hasParent(x,y) ^ hasBrother(y,z) => hasUncle(x,z)). Далее все просто: дядя — это все такие объекты x, что x принадлежит Person и существует такой y (племянник(ца)), что hasUncle(y,x). Заметим, что этот класс можно описать в OWL 2 в котором появились property chains, но не в OWL 1.

2) Класс «любитель кошек» (CatLover). Подразумевая класс «Кошка» (Cat) и свойство «любить» (loves)  надо выразить класс любителей кошек. Каждый экземпляр CatLover любит *всех* экземпляров Cat.

linkLover o (inverse linkCat) SubPropertyOf: loves
CatLover SubClassOf (linkLover some {link})
Cat SubClassOf (linkCat some {link})

Иллюстрация:

catlover

Смысл в том, что используется вспомогательный экземпляр (link), который связывает   любителей кошек и самих кошек. В OWL легко сказать, что *каждый* любитель кошек связан с link при помощи свойства linkLover, и *каждая* кошка связана с link при помощи свойства linkCat (описания свойств тривиальны). Далее остается последний шаг: сказать, что любая цепочка «любитель кошек -> link ->  кошка» означает свойство «любить» (loves). Желающие могут проверить в Protege, что для любого x из класса CatLover и любого y из класса Cat, reasoner сможет вывести loves(x,y). Если не сможет — то это баг (мой или reasoner’a). При этом ему будет гораздо сложнее вывести, что некий объект x является экземпляром CatLover, поскольку в OWL это не будет следовать даже если x будет любить всех кошек *явно* перечисленных в онтологии (для желающих понять почему: почитайте про Open World Assumption).

Я заранее согласен со всеми, кто скажет, что подобное решение слишком сложно для такой простой проблемы. Возможно. К сожалению, логические языки, в которых это решается легко (в частности в логике предикатов), сложнее OWL в вычислительном смысле. Возможно мне стоит создать страничку для обсуждения применимости OWL вообще (только я не хочу делать это на *этой* странице).

3) Класс «Разнородный контейнер» (MixedContainer).

Условие задачи и варианты решения см. здесь!

4) Ждем предложений следующей задачки! (а вы думали, что я один буду трудиться? )

Начало положено, продолжение следует. Обязательно задавайте вопросы и присылайте свои примеры (даже если вы не знаете, как их выразить в OWL).

52 Responses to Уголок OWL

  1. Ganimede:

    А как же тогда в OWL будет Тетя?

  2. Добавляется аналогичная цепочка свойств:
    hasParent o hasSister => hasAunt

  3. ну тетей также может быть просто жена дяди, и наоборот(дядей муж тети):)

  4. Мой «Дядя» не может (см. определение) :) Ничто не мешает всем желающим расширить определение дяди и тети и прислать пример в OWL.

  5. me.yahoo.com/a/2pDbV7k3x…:

    Ага, а у оптимизатора запросов потом дым из ушей пойдёт. Пользователи РЕФАЛа тоже любили записать чего-нибудь предельно компактно, получались хорошие тесты для компилятора, обычно он их даже проходил 😉

  6. А Вы не гадайте, что пойдет у кого и откуда, а что нет. Попробуйте. Я буду рад обсудить возможные проблемы. Только не на этой странице, здесь обсуждается семантика.

  7. Nata_Ke:

    А оператор «that» в манчестерском синтаксисе, его там нет? :)
    CatLover(попробуем так(чистый OWL 1.0)):
    Class: Cat
    Class: Person
    objectProperty: loves
    Class: CatLover:
    EquivalentTo: loves allValuesFrom Cat
    А если задать
    objectProperty: loves
    domain: Person
    range: Cat

  8. «that» в манчестерском синтаксисе — это тоже самое, что and, т.е. пересечение.
    Нет, увы, allValuesFrom (в манчестерском синтаксисе — only) недостаточно. Скажем, объект, который не любит *никого* вполне может быть экземпляром (loves only Cat) :)
    Более того, (loves only Cat) говорит, что «_все_, кого любят данные объекты, являются кошками». Но это не значит, что «они любят _всех_ кошек». Понятна разница? :)

  9. Ganimede:

    Что-то сложно понять разницу в постпраздничный вечер!? Тем более трудно поддается осознанию как объект, который не любит никого, может быть экземпляром (loves only Cat)?

  10. Такова семантика only (или allValuesFrom). Если преобразовать конструкцию (loves only Cat) в формулу в логике первого порядка, то получим: \forall y, loves(x,y) -> Cat(y). Т.е. это обычная импликация вида A -> B. Если A ложно, то вся импликация тривиальным образом истинна. Так и тут, мы говорим: «если объект класса CatLover кого-то любит, то это кошка». Объект, который не любит *никого* это определение никоим образом не нарушает.

  11. А вот если использоваль логику предикатов, то верно ли будет так:
    \IsExist X( \forall Y, ( Person(X) \and Cat(Y) \and loves(X,Y)))

  12. Не совсем. Ты делаешь слишком уж сильное утверждение («для каждого Y верно Cat(Y)…»). Вполне достаточно «\forall y, person(x) ^ cat(y) -> loves(x,y)». Другими словами интерпретация CatLover должна быть такой:
    I(CatLover) = {x \in I(Person), такие что: (x,y) \in I(loves) для всех y \in I(Cat)}
    Проблема в том, что конструкции «loves some Cat» и «loves only Cat» в OWL такую семантику сами по себе обеспечить не могут. Первая говорит: «любит _хотя_бы_одну кошку», а вторая: «любит _только_ кошек». А нам надо «любит _всех_ кошек».

  13. Nata_Ke:

    Дело не в людях, а в кошках: не существует кошки, которую не любит CatLover

  14. Вот именно. Осталось сформулировать это в OWL. (loves only Cat) не запрещает существование кошек, которых не любят :) Это только говорит, что все кого любят — кошки.

  15. Nata_Ke:

    А если вдобавок к описанию CatLover:
    Cat equivalentTo (inverse loves) hasValue CatLover

  16. Уже ближе, но пока не то. Это говорит, что каждую кошку любит хотя бы один любитель кошек :) Но при этом по-прежнему могут существовать любители кошек, которые любят не всех кошек. Непорядок! :)

  17. Nata_Ke:

    нет, hasValue тоже мимо, т.к. требует экземпляр…

  18. А если попробовать от противного — запретить существование кошех, которых не любит CatLover

    Class: Cat
    DisjointWith: not (inverse loves only CatLover)

  19. Идея неплоха, но реализация пока не дотягивает :) Class: Cat
    DisjointWith: not (inverse loves only CatLover)
    это то же самое, что:
    Class: Cat
    SubClassOf: inverse loves only CatLover
    или по-русски: «все, кто любят кошек являются любителями кошек». Это не то, что нам надо, так как:
    1) Это не означает, что каждую кошку любят *все* любители кошек.
    2) В условии не сказано, что кошек могут любить *только* любители кошек. Например, Вася может любить какую-то одну, конкретную кошку, не являясь при этом любителем кошек :)

  20. Nata_Ke:

    Еще вариант: объявить индивидуала CatLover1 как CatLover’a, и сказать, что кошки — это все кого CatLover1 любит?
    Class: Person
    ObjectProperty: loves
    objectProperty: lovedBy inverse loves

    CatLover subclassof (Person and loves some Cat)
    individual: CatLover1 type:CatLover
    Class:Cat subclassof (lovedBy someValuesFrom(CatLover1)))

  21. Отлично, пол-решения есть! Теперь каждая кошка любима. Осталось только чтобы она была любима *всеми* любителями кошек, а не только catLover1 :)
    Хинт: этот дополнительный экземпляр действительно нужен. Он будет присутствовать в решении.

  22. Nata_Ke:

    Class: CatLover subclassof (not(loves only not(Cat))

  23. Не, ну это ведь то же самое, что и CatLover SubClassOf (loves some Cat)

    Стандартная связь между кванторами: R some C = not (R only not (C))

  24. vvi:

    Добрый день, сначала эмоции:
    Если ЭТО только «пол-решения», то я разделяю скептическое замечание пользователя с OpenID (me.yahoo.com/a/2pDbV7k3x8ctHq1V7BXayPlxEx9S#71ed9).
    Как говорится, умные люди знают как решать проблемы, а мудрые стараются их не создавать.
    С точки зрения логического вывода не оптимально: при создании нового экземпляра CatLover явно создаются N связей со всеми экземплярами Cat?
    При выяснении членства некоторого Х в классе CatLover надо проверить наличие тех же N связей со всеми экземплярами Cat?

    А теперь по-существу:
    Создаем:
    1) Класс «Животное».
    2) Экземпляр «Кошка» из класса «Животное»
    3) Тривиальное ограничение hasValue на свойство loves для класса CatLover, которое делает всю «черную работу».

    Итог: каждый экземпляр CatLover «любит» «Кошку».

    Положительные черты:
    1) никаких CatLover1 не нужно,
    2) меньше someValuesFrom, inverse и пр.

    Отрицательные черты:
    1) надо ещё определить Класс «Cat», например, через дополнительное свойство myURI:type (значением этого свойства для всех экземпляров класса «Cat» будет всё та же «Кошка»)
    2) предвижу критику за «корректировку» условий задачи — куда деваться 😆

  25. По порядку:
    >>>при создании нового экземпляра CatLover явно создаются N связей со всеми экземплярами Cat?

    Конечно нет. Никто не говорил, что у нас вообще конечное (или тем более ограниченное сверху) число кошек.

    >>>При выяснении членства некоторого Х в классе CatLover надо проверить наличие тех же N связей со всеми экземплярами Cat?

    Тоже нет. У нас все таки логика, а не проверка констрейнтов в closed world, а-ля база данных.

    >>>предвижу критику за “корректировку” условий задачи — куда деваться

    Критики не будет. Это простая другая задача. Мы же продолжаем обсуждать прежнюю :)

  26. vvi:

    >>> Никто не говорил, что у нас вообще конечное (или тем более ограниченное сверху) число кошек.

    no comments.

    >>>>>>При выяснении членства некоторого Х в классе CatLover надо проверить наличие тех же N связей со всеми экземплярами Cat?

    >>>Тоже нет. У нас все таки логика, а не проверка констрейнтов в closed world, а-ля база данных.

    Тогда хотелось бы узнать, как же определить членство произвольного Х в классе CatLover?
    Пока остается хоть одна нелюбимая Х-м кошка, Х не принадлежит CatLover.
    В свете первого замечания, это тем более странно — сколько проверок будет выполнено?

    >>>>>>предвижу критику за “корректировку” условий задачи — куда деваться

    >>>Критики не будет. Это простая другая задача. Мы же продолжаем обсуждать прежнюю

    Формально, ни одно условие исходной задачи не нарушено.

  27. >>>Тогда хотелось бы узнать, как же определить членство произвольного Х в классе CatLover?

    Как обычно в логике: из базы знаний O следует «a \in C» тогда и только тогда, когда O вместе с «a \in not(C)» противоречиво.

    >>>Пока остается хоть одна нелюбимая Х-м кошка, Х не принадлежит CatLover.

    Не «остается», а «может существовать, не противоречя существующим знаниям».

    >>>В свете первого замечания, это тем более странно — сколько проверок будет выполнено?

    Здесь очевидна путаница в понятиях. В базе знаний бесконечное число кошек непредставимо (как и в базе данных). Интерпретации же классов вполне могут быть бесконечными (или как минимум неограниченно большими). Несложно привести пример класса, который попросту не имеет конечной интерпретации. Это нормально в OWL (и в Semantic Web вообще).

    >>>Формально, ни одно условие исходной задачи не нарушено.

    Вы действительно считаете, что ограничив класс кошек до единственного экземпляра, вы решаете ту же задачу?

  28. Nata_Ke:

    Хм, я хотела сказать CatLover subclassof (not loves) only (not Cat), но Protege этого не позволяет :) т.е. отрицание ролей надо сделать как-то по-другому.

  29. Ааа, это не Protege, этого OWL не позволяет. Можно использовать not R(a,b) для двух конкретных экземпляров, но нельзя использовать отрицательные роли в сложных выражениях классов. Вот тут как раз у reasoner’ов начинает идти пар из ушей — проверено :)

  30. Nata_Ke:

    Хорошо, добавим экземпляр кошки и скажем, что все кто ее любят — CatLover-ы.
    individual: Cat1 type:Cat
    CatLover subclassof (loves some (Cat1))

  31. Верно, только если у нас позже появится еще одна кошка, скажем cat2, то reasoner не сможет автоматически вывести, что ее любят все CatLover’ы :) А в этом весь смысл..
    Ладно, сейчас нарисую картинку и попробую объяснить решение (заранее готовясь к обвинениям в решении надуманных проблем :)

  32. Nata_Ke:

    да, Protege уже не вывел…

  33. Nata_Ke:

    А если дописать так:
    CatLover subclassof (loves only isLovedBy {CatLover1}

  34. vvi:

    >>>>>>Тогда хотелось бы узнать, как же определить членство произвольного Х в классе CatLover?

    >>>Как обычно в логике: из базы знаний O следует “a \in C” тогда и только тогда, когда O вместе с “a \in not(C)” противоречиво.

    И конечно всё опять зависит от О (читай: контекст)?

    >>>>>>Пока остается хоть одна нелюбимая Х-м кошка, Х не принадлежит CatLover.

    >>>Не “остается”, а “может существовать, не противоречя существующим знаниям”.
    Хорошо.

    Тогда, может быть, Вы поясните, что это за таинственное «не противоречя существующим знаниям»?

    >>>>>>В свете первого замечания, это тем более странно — сколько проверок будет выполнено?

    >>>Здесь очевидна путаница в понятиях. В базе знаний бесконечное число кошек непредставимо (как и в базе данных). Интерпретации же классов вполне могут быть бесконечными (или как минимум неограниченно большими). Несложно привести пример класса, который попросту не имеет конечной интерпретации. Это нормально в OWL (и в Semantic Web вообще).

    Из чего я делаю вывод, что ответ на вопрос «сколько проверок будет выполнено?» состоит в следующем: «либо конечное, либо бесконечное число».
    Поправьте, если я ошибаюсь и, ответьте.
    В моем варианте ровно 1.

    >>>>>>Формально, ни одно условие исходной задачи не нарушено.

    >>>Вы действительно считаете, что ограничив класс кошек до единственного экземпляра, вы решаете ту же задачу?

    Прочитайте внимательно мой пост. Цитирую:
    «…
    1) надо ещё определить Класс “Cat”, например, через дополнительное свойство myURI:type (значением этого свойства для всех экземпляров класса “Cat” будет всё та же “Кошка”)
    …»

    Экземпляр “Кошка” класса «Животное» играет роль типа (если хотите, метакласса). Это совсем не то же самое, что Cat1 в выражении individual: Cat1 type:Cat.
    Этих Cat_i (экземпляров Cat) может быть сколько угодно.

  35. Nata_Ke:

    Если «Экземпляр “Кошка” класса “Животное” играет роль типа(если хотите, метакласса)», то это не OWL-DL, а уже OWL-Full, в котором логический вывод уже не выходит.

  36. Даа… Впечатляет решение 😯
    Но все понятно и логично. На мой взгляд, очень хорошо, что Павел указал на семантику Only, т.к. ранее у меня было неверное ее понимание. Спасибо!

  37. vvi:

    >>>Если “Экземпляр “Кошка” класса “Животное” играет роль типа(если хотите, метакласса)”, то это не OWL-DL, а уже OWL-Full, в котором логический вывод уже не выходит.

    Я такой связи не вижу — формально это все таки остается DL.
    Поясните, пожалуйста Вашу мысль.
    А условие про Full Вы сами придумали?
    Про логический вывод и речи в задаче не было.

  38. Nata_Ke:

    реальной подсказкой была бы оговорка «не OWL 1.0!»
    Павлу — благодарность!

  39. >>>Если “Экземпляр “Кошка” класса “Животное” играет роль типа(если хотите, метакласса)”, то это не OWL-DL, а уже OWL-Full, в котором логический вывод уже не выходит.

    Не, это просто номинал, они вполне есть в OWL 1.0 (в SHOIN(D) номиналы входят). Но на будущее оговорюсь — решения интересны именно в разрешимых языках (т.е. OWL Full не подойдет).

  40. >>>И конечно всё опять зависит от О (читай: контекст)?

    Конечно.

    >>>Тогда, может быть, Вы поясните, что это за таинственное “не противоречя существующим знаниям”?

    Ничего таинственного. Это значит что добавление a \in not(C) к существующей онтологии не приводит к потере согласованности.

    >>>Из чего я делаю вывод, что ответ на вопрос “сколько проверок будет выполнено?” состоит в следующем: “либо конечное, либо бесконечное число”.
    Поправьте, если я ошибаюсь и, ответьте.
    В моем варианте ровно 1.

    Нисколько не будет. В них просто нет смысла. Я же написал: просто проверив, что x любит всех кошек в базе знаний О вы все равно не докажете, что x — любитель кошек. В OWL это банально неверно. Вот если б определением CatLover было б «любит не менее N кошек», то вот тут — да, reasoner’у пришлось бы честно считать.

    >>>Прочитайте внимательно мой пост. Цитирую:

    Возможно, я Вас не понял. Наверное будет лучше, если Вы приведете все же решение на формальном языке. А то у меня такое ощущение, что после этого мы получим то же решение, что и у меня, только с «Кошка» вместо link. Если нет, то будет интересно посмотреть.

  41. vvi:

    Всем спасибо за интересное обсуждение.
    Павлу — отдельное.
    Насчет формального описания — уже не сегодня.

    С уважением,
    Владимир

  42. Смотрю один читатель за нашу работу над Уголком OWL поставил один бал с пяти возможных. Видимо он считает нашу работу достойной и за это ему благодарность от коллектива 😎

  43. Ganimede:

    вопрос по синонимам — как представить синонимичные понятия в OWL? например, «источник» и «ключ». Для связки SameAs можно применить?

  44. Nata_Ke:

    Если «источник» и «ключ» — индивидуалы (экземпляры концептов), то » sameAs».
    Например: источник: type:Класс1 sameAs: ключ: type:Класс2
    Если «источник» и «ключ» — сами концепты, то «EquivalentTo».
    Например: type: источник EquivalentTo: type: ключ.
    Либо EquivalentClasses: type:источник type:ключ
    Если «источник» и «ключ» — свойства, то есть аналоги:
    EquivalentProperties: data/objectProperty:источник data/objectProperty:ключ
    или
    data/objectProperty:источник EquivalentTo: data/objectProperty:ключ

  45. Подскажите как лучше смоделировать на OWL объект разведенная персона DivorcedPerson- т.е. гражданин — ранее состоявший в браке с гражданином XXX с противоположенным полом.

    Можно предположить наличие таких концептов как:

    Person — все граждане, где у каждого определен пол

    MarriedPerson — гражданин имеющий супруга — другого гражданина противоположного пола

    Если необходимо задайте еще концептов, через которые можно определять. Может я что-то не определил — уточню если необходимо

  46. Дело в том, что у OWL нет возможностей темпоральной логики, поэтому полноценно выразить «_ранее_ состоявший» не удастся. Поэтому придется просто вводить свойства isMarried (сейчас женат) и wasMarried (был женат)
    а дальше что-то вроде:
    DP = Person and wasMarried some Person
    Возможно имеется в виду, что либо человек женат, либо разведен (но не то и другое вместе). Этого можно добиться таким образом:
    DP = Person and wasMarried some Person and isMarried all Nothing
    Тогда reasoner сам выведет, что DP и MP — disjoint (если MP объявлен как Person and isMarried some Person).
    Осталось только добиться обязательной противоположности пола (кстати, подумай, стоит ли в наше время это требовать :) ). Если считаешь, что обязательно, то можем вынести задачку на обсуждение, тут могут быть и решения в лоб и позаковыристее…

  47. Nata_Ke:

    Как можно определить свойство younger/older, которое по известным значениям hasAge определяло, кто кого старше?(hasAge взят из OWL2 primer)

  48. Не получится. Я знаю, звучит разочаровывающе, но пока это нельзя. Максимум чего можно добиться — это разбить людей на группы по возрастам (<10, 11-15, 16-20, etc) с помощью data facet в OWL 2, а затем писать, что каждый экземпляр группы 10-15 младше каждого из группы 16-20. Коряво, но что делать.
    С data properties вообще много проблем. Например, нельзя написать класс людей, чье отношение рост/вес (BMI — body mass index) меньше какого-то порогового значения. Мы отправили proposal на эту тему [1].
    Наталья, может Вы напишите ваш use case в public-owl-dev? Обсудим..

    [1] http://www.w3.org/TR/2009/WD-owl2-dr-linear-20090421/

  49. Противоположность пола — для моей задачи обязательна(по крайней мере пока :smile: ). Но тут меня как раз это вопрос и интересует: т.е. зависимость ограничения на свойство от указания его домена.
    Можно ли здесь использовать подствойство:

    Class: Man

    Class: Woman
    DisjontWith: Man

    Class: DP
    EquvalentTo: Woman and wasMarried some Man and isMarried max 0 or Woman isMarried some Man and isMarried max 0

  50. Извиняюсь — опечатался — вот так:
    Class: Man

    Class: Woman
    DisjontWith: Man

    Class: DP
    EquvalentTo: Woman and wasMarried some Man and isMarried max 0 or Woman wasMarried some Man and isMarried max 0

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *


Ответить с помощью ВКонтакте: