Создайте людей внутри правил Йены

У меня есть онтология со многими людьми, и я использую рассуждения Йены, чтобы получить информацию о них. Моя цель состоит в том, чтобы создавать новых людей на основе заданной информации внутри этих правил и назначать им свойства. Люди не должны быть названы, но им нужен тип и они должны быть частью нескольких свойств. На данный момент я могу создавать анонимных людей (с помощью сообщения в списке рассылки), но я могу дать им только один тип или одно свойство.

Вот маленький пример моей проблемы; мое правило выглядит так (онтологию и предполагаемый результат можно найти внизу):

[test2: (? X rdf: тип NS: Test1) ->
[(? Y rdf: тип NS:Test2) <- makeSkolem (? Y,? X)]]

Это означает, что когда индивидуум Test1 найден, то создается новый пустой узел, и затем этому узлу присваивается тип Test2. Это прекрасно работает, но я хочу дать этим новым лицам классификацию и указатель (свойство) на?X (люди Test1).

Нечто похожее на следующее не работает, так как "обратные правила допускают только одно предложение head". Каждый пункт для его одного работает отлично все же.

[test2: (? X rdf: тип NS: Test1) ->
[(? Y rdf: тип NS:Test2), (?Y NS:hasClassification 'test'), <- makeSkolem (? Y,? X)]]

Это моя онтология:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns="file:/Test#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" > 
  <rdf:Description rdf:about="file:/Test#hasClassification">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#TestProp">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd2">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test1">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test2">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
  </rdf:Description>
</rdf:RDF>

Это результат первого правила (пустые узлы с идентификаторами A0 а также A1 новые лица):

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns="file:/Test#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" > 
  <rdf:Description rdf:about="file:/Test#hasClassification">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#DatatypeProperty"/>
  </rdf:Description>
  <rdf:Description rdf:nodeID="A0">
    <rdf:type rdf:resource="file:/Test#Test2"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#TestProp">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#ObjectProperty"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#testInd2">
    <rdf:type rdf:resource="file:/Test#Test1"/>
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#NamedIndividual"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test1">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test#Test2">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Class"/>
  </rdf:Description>
  <rdf:Description rdf:nodeID="A1">
    <rdf:type rdf:resource="file:/Test#Test2"/>
  </rdf:Description>
  <rdf:Description rdf:about="file:/Test">
    <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Ontology"/>
  </rdf:Description>
</rdf:RDF>

1 ответ

Решение

Во-первых, обратите внимание, что ваше правило не делает то, что вы сказали, что оно делает.

[test2: (?X rdf: тип NS:Test1) →
[(? Y rdf: тип NS:Test2) ← makeSkolem(?Y,?X)]]

Это означает, что когда индивидуум Test1 найден, то создается новый пустой узел, и затем этому узлу присваивается тип Test2.

Правило совпадает, когда найден экземпляр NS:Test1, и добавляет новое правило обратной цепочки, которое можно использовать при определении, имеет ли что-то тип NS:Test2: если это сколем из?X, то он имеет этот тип. Он не дает ничего типа NS: Test2, если вы не попросите об этом. (Написание всей модели, конечно же, требует таких троек.)

Если вы считаете такой тип поведения приемлемым, вы можете просто использовать правило прямой цепочки, которое добавляет несколько правил обратной цепочки, например:

[Test2:
(? X rdf: тип NS:Test1) →
[(? Y rdf: тип NS: Test2) ← makeSkolem (? Y,? X)],
[(? Y NS: hasClassification 'test') ← makeSkolem (? Y,? X)]
]

Я думаю, что это немного сложнее, чем нужно. Объекты Skolem - это просто объекты, которые однозначно определяются некоторыми другими значениями, поэтому вы можете использовать makeSkolem в предварительных условиях правила, а также в заголовке правила. Это означает, что вы можете сделать это:

[test2: (?X rdf: тип NS:Test1), makeSkolem (? Y,? X) →
(? Y rdf: тип NS:Test2), (?Y rdf: тип NS:hasClassification 'test')]

Стоит отметить, что makeSkolem принимает произвольное количество аргументов. Возможно, стоит добавить какой-нибудь индикатор, чтобы случайно не получить один и тот же объект сколем в нескольких местах. Например, если у вас было что-то вроде

[(?child rdf:type:Child), makeSkolem(? мать,? ребенок) →
(? mother rdf: type: Mother), (? child: hasMother? mother)]

[(?child rdf:type:Child), makeSkolem(? папа,? ребёнок) →
(? папа rdf: тип: папа), (? child: hasFather? папа)]

тогда вы фактически создадите только один объект сколем для каждого ребенка и назовете его "Мать и отец ребенка", что, вероятно, не то, что вы хотите. Вместо этого вы можете сделать что-то вроде:

[(? child rdf: type: Child), makeSkolem ("мама", "ребенок", "мама") →
(? mother rdf: type: Mother), (? child: hasMother? mother)]

[(? child rdf: type: Child), makeSkolem ("отец", "ребенок", "отец") →
(? папа rdf: тип: папа), (? child: hasFather? папа)]

поскольку (?child, 'mother') а также (?child, 'father') всегда разные, вы получаете два сколем объекта вместо одного. Вы можете использовать что-то подобное в своем правиле, например,

[test2: (?X rdf: тип NS:Test1), makeSkolem (? Y,?X, 'test2') →
(? Y rdf: тип NS:Test2), (?Y NS:hasClassification 'test')]

Другие вопросы по тегам