От математического выражения к правилу Йены
Пусть A = {x1, x2,…, xn}. Мы хотим вычислить разницу между xi и xj, где xj - это min {x ∈ A: x> xi }. Можно ли перевести такое выражение в правило Йены?
1 ответ
Да, вы можете сделать это как в Jena Rules, так и в Jena ARQ (механизм обработки запросов для SPARQL).
Настройка
Допустим, вы определили структурированное представление ваших данных. Для Xi у вас есть объект, который соответствует чему-то вроде этого (N3):
[ a :Entry
; :hasEntryValue 4.3
]
Затем для вашего набора A вы можете определить его значения как RDF Collection, например, rdf: List. Следующие N3, например, описывают множество A={4.3, 4.2}.
[ a :Set
; dct:identifier "A"
; entries ( [ a :Entry
; :hasEntryValue 4.3
][ a :Entry
; :hasEntryValue 4.2
] )
] .
В Йенских Правилах
В правилах Йены вы могли бы написать что-то вроде:
[calculate: ( ?set rdf:type :Set ),
( ?set rdfs:member ?x0 ),
nextSmallest( ?set ?x0 ?x1 ),
makeSkolem( ?calculated ?x0 ?set),
difference( ?difference ?x0 ?x1)
-> (?calculated :hasValue ?difference),
(?calculated :derivedFrom ?x0),
(?calculated :derivedFrom ?x1)
]
Это потребует от вас построить Джену Билтин для nextSmallest
часть запроса. Приведенное выше правило для заданного значения ?x0
в пределах определенного набора,?set
Попытка определить nextSmallest
элемент, ?x1
и (если это удастся) построить новый узел, ?calculated
и связать ?difference
с помощью какого-то доменного :hasValue
имущество. Как примечание стиля, я также представил :derivedFrom
свойство, чтобы отследить, откуда пришел этот узел, чтобы он не был бесполезен в качестве результата вычисления.
В ARQ / SPARQL
Первый вопрос заключается в том, хотите ли вы, чтобы результаты отображались на вашем графике вместе с вашими данными (как в подходе, основанном на правилах) или вы просто хотите получить результаты. Если вы просто хотите получить результаты, у вас есть выбор относительно того, будут ли результаты представлены в графической форме. Самый простой подход будет просто SELECT
результаты, достижения:
SELECT ?set ?x0Val (BIND(?x1Val-?x0Val) AS ?difference) WHERE {
?set rdf:type :Set .
?set rdfs:member ?x0 .
?set rdfs:member ?x1 .
?x0 :hasEntryValue ?x0Val .
?x1 :hasEntryValue ?x1Val .
FILTER( ?x0Val < ?x1Val )
FILTER NOT EXISTS {
?set rdfs:member ?otherEntry .
?otherEntry :hasEntryValue ?otherVal .
FILTER( ?x0Val < ?otherVal && ?otherVal < ?x1Val ) .
}
}
Вышеупомянутый запрос был написан с моей головы, поэтому, возможно, понадобятся некоторые изменения. Суть в том, что вы извлекаете любые два элемента коллекции и ориентируете их так, чтобы ?x0
является меньшим из двух. Затем вы выбрасываете связанные пары, если между ними существует какая-либо пара. Механизм запросов будет учитывать декартово произведение множества при выборе привязок для ?x0
а также ?x1
в том числе когда sameTerm(?x0, ?x1)
так что используя FILTER( ?x0Val < ?x1Val )
обеспечивает быстрый способ отказаться от тривиально плохих привязок.