Реализация вывода правил SHACL через выражение в sh: объект - PullRequest
0 голосов
/ 16 апреля 2020

В настоящее время я пытаюсь вывести новое свойство maps:mapstoclass на основе приведенных ниже троек. Идея заключается в том, что я могу использовать вывод (вместе с файлом rdf, содержащим выравнивание классов data:), чтобы определить сходство между data0:object100 и его перекрывающимися объектами из data1:, указанного в maps:hasOverlap.

maps:relation_obj1  a     maps:OverlapRelations ;
        maps:hasOverlap   [ a                      data1:classA ;
                            maps:mainRelativeArea  "80.0"^^xsd:float ;
                            maps:secRelativeArea   "100.0"^^xsd:float ;
                            maps:secfeature        data1:object1 ;
                          ] ;
        maps:hasOverlap   [ a                      data1:classX ;
                            maps:mainRelativeArea  "40.0"^^xsd:float ;
                            maps:secRelativeArea   "100.0"^^xsd:float ;
                            maps:secfeature        data1:object2 ;
                          ] ;
        maps:mainfeature  data0:object100 ;
        maps:mainclass     data0:classB .

Сначала я посмотрел, удовлетворяют ли свойства объекта maps:hasOverlap моему qualifiedValueShape (формы / правила shacl приведены в конце). В этом случае только объект hasOverlap с maps: secfeature data1: object1 удовлетворяет условию. Таким образом, объект 'maps: mapsto' должен быть data1: object1. Результат, который я ожидаю:

maps:relation_obj1 maps:mapstoclass data1:object1. 

Тем не менее, в настоящее время я получаю:

maps:relation_obj1 maps:mapstoclass data1:object1, data1:object2.

Что я делаю не так? Требуется ли явное применение sh: условия правила в sh: object? Я посмотрел на выражения узла, но не смог его использовать - и я не смог найти соответствующие примеры в документации.

Используемые формы:

ex:mainAreaShape
    rdf:type sh:NodeShape;
    sh:property [
        sh:path maps:mainRelativeArea ;
        sh:minInclusive 80 ;
    ].

ex:secAreaShape
    rdf:type sh:NodeShape;
    sh:property [
        sh:path maps:secRelativeArea ;
        sh:minInclusive 80 ;
    ].


ex:OverlapRelations
    rdf:type rdfs:Class, sh:NodeShape ;
    sh:targetClass maps:OverlapRelations;
    rdfs:label "whether overlap between features is enough to generate relation" ;
    sh:rule [
        rdf:type sh:TripleRule ;
        sh:subject sh:this ;
        sh:predicate maps:mapstoclass;
        sh:object [sh:path (maps:hasOverlap
                    rdf:type) ;
                    ];  
        sh:condition ex:OverlapRelations;
        sh:condition [
            sh:property [
            sh:path maps:hasOverlap ;
            sh:nodeKind sh:BlankNode ;
            sh:minCount 1;
            sh:qualifiedValueShape [
                    sh:and (ex:mainAreaShape ex:secAreaShape);  
                                    ];
                    sh:qualifiedMinCount 1;
                    sh:qualifiedMaxCount 1;
                        ];
                    ];
            ].

1 Ответ

0 голосов
/ 17 апреля 2020

Условие sh: только отфильтровывает узлы фокуса, к которым применяется правило, но не влияет на оценку объекта sh:. В вашем случае, не проверяя, я предполагаю, что ваш (один) узел фокусировки отображает: отношение_объект действительно выполняет условие, потому что одно из его значений соответствует QVS. Тем не менее, sh: выражение объекта по-прежнему оценивается для всех значений карт путей: hasOverlap / rdf: type, который затем предоставляет оба типа.

Один из вариантов будет express чем вам нужно в SPARQL и использовать правило на основе SPARQL.

Другой вариант - переместить логи c, находящиеся в состоянии sh:: в выражение sh: объектный узел. Я считаю sh: здесь можно использовать filterShape

https://w3c.github.io/shacl/shacl-af/#node -expressions-filter-shape

. Помните, что выражения узлов в основном представляют собой конвейеры, где узлы go находятся на одной стороне, а другие узлы go находятся на другой стороне. В вашем случае, я думаю, что вы хотите

  1. начать со всех значений карт: hasOverlap
  2. , а затем отфильтровать только те, к которым применяется ваша форма значения, то есть filterShape sh: и ( ex: mainAreaShape ex: secAreaShape)
  3. из них возвращают rdf: type

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

sh:object [  # 3.
    sh:path rdf:type ;
    sh:nodes [ # 2.
        sh:filterShape [ 
            sh:nodeKind sh:BlankNode ;
            sh:node ex:mainAreaShape, ex:secAreaShape ;  # same as your sh:not
        ] ;
        sh:nodes [ # 1.
            sh:path maps:hasOverlap ;
        ]
    ]
]

Вам необходимо «прочитать» выражения узла изнутри, поэтому сначала оценивается самый внутренний путь hasOverlap, а затем результаты, которые проходят через фильтр. Если нет результирующих узлов или у них нет rdf: типа, тогда sh: объект не найден и, следовательно, нет тройного вывода.

Кстати, sh: targetClass не нужен, и я думаю, что все это также можно выразить, используя (более новое) ключевое слово sh: values ​​как

ex:OverlapRelations
    a rdfs:Class, sh:NodeShape ;
    rdfs:label "whether overlap between features is enough to generate relation" ;
    sh:property [
        sh:path maps:mapstoclass ;
        sh:values [ # 1.
            sh:path rdf:type ;
            sh:nodes [ # 2.
                sh:filterShape [ 
                    sh:nodeKind sh:BlankNode ;
                    sh:node ex:mainAreaShape, ex:secAreaShape ;
                ] ;
                sh:nodes [ # 1.
                    sh:path maps:hasOverlap ;
                ]
            ]
        ]
    ] .

Опять не проверено, поэтому прошу прощения за любые ошибки:)

...