How to use :notIncludes in Notation 3 rules? - semantic-web

I'm currently learning how to use the rules in Notation 3 with CWM.
I want to build a rule that gives the stepchilds in a family ontology. So, the stepchild is the child of someone but not the child of this someone's spouse.
#prefix ex: <http://www.smith-family.com/familyOntology.owl#> .
#prefix log: <http://www.w3.org/2000/10/swap/log#>.
{
?p1 :hasWife ?p2 .
?p2 :hasChild ?c .
: log:notIncludes {?p1 :hasChild ?c}
}
=> {?p1 :hasStepChild ?c}.
I don't really understand how to use notIncludes...
Also, I miss the ?p1 :hasHusband ?p2 statement, but it even does not work like that.
Does anyone know how I could make it work?

You have to specify the dataset and what the negation as failure is applied to. See https://www.w3.org/2000/10/swap/doc/paper/#neg23 for reference.

Related

How to get the connected graph between 2 resources in RDF Graph [duplicate]

If this is the RDF graph , given the resource A , I need to construct all the triples connected to A till the end . here i have to get the graph include B,C,D,E
After that, suppose I've got this graph and want to go only from the starting point (:A) and get the subgraph produced by following the paths that end with an edge on property :d. For instance, if A1 is given as the starting point, and d as the property, we'd construct:
:A1 :a :B1,
:B1 :b :S1,
:B1 :b :S2,
:S1 :d :D1,
:S2 :d :D2,
The first case
To get the whole connected graph, you need to use a wildcard property path to follow most of the path, and then grab the last link with an actual variable. I usually use the empty relative path in constructing wildcards, so as to use <>|!<> as the wildcard, but since you mentioned that your endpoint doesn't like it, you can use any absolute IRI that you like, too. E.g.,
prefix x: <urn:ex:>
construct { ?s ?p ?o }
where { :A (x:|!x:)* ?s . ?s ?p ?o . }
This works because every property is either x: or not, so x:|!x: matches every property, and then (x:|!x:)* is an arbitrary length path, including paths of length zero, which means that ?s will be bound to everything reachable from :a, including :a itself. Then you're grabbing the triples where ?s is the subject. When you construct the graph of all those triples, you get the subgraph that you're looking for.
Here's an example based on the graph you showed. I used different properties for different edges to show that it works, but this will work if they're all the same, too.
#prefix : <urn:ex:> .
:A :p :B, :C .
:B :q :D .
:C :r :E .
:F :s :G .
:G :t :H .
prefix x: <urn:ex:>
prefix : <urn:ex:>
construct {
?s ?p ?o
}
where {
:A (x:|!x:)* ?s .
?s ?p ?o .
}
Since this is a construct query, the result is a graph, not a "table". It contains the triples we'd expect:
#prefix : <urn:ex:> .
:C :r :E .
:B :q :D .
:A :p :B , :C .
The second case
If you want to ensure that the paths end in a particular kind of edge, you can do that too. If you only want the paths from A1 to those ending with edges on d, you can do:
prefix x: <urn:ex:> #-- arbitrary, used for the property path.
prefix : <...> #-- whatever you need for your data.
construct {
?s1 ?p ?o1 . #-- internal edge in the path
?s2 :d ?o2 . #-- final edge in the path
}
where {
:A (x:|!x:)* ?s1 . #-- start at :A and go any length into the path
?s1 ?p ?o1 . #-- get the triple from within the path, but make
?o1 (x:|!x:)* ?s2 . #-- sure that from ?o1 you can get to to some other
?s2 :d ?o2 . #-- ?s2 that's related to an ?o2 by property :d .
}
The most important part of an RDF graph is the properties. Since your diagram does not define the properties, the question is rather ambiguous, but comes down to a couple of scenarios.
If the property is the same in the graph, then a transitive property path can be used:
CONSTRUCT {:A :prop ?rsc }
WHERE {
:A :prop* ?rsc .
}
If there are multiple types pf properties in the graph, it is more complicated to get the transitive closure. For example the following will get all properties in the example graph:
CONSTRUCT {
:A ?p ?rsc1 .
:A ?p1 ?rsc2 .
}
WHERE {
:A ?p ?rsc1 .
OPTIONAL {?rsc1 ?p1 ?rsc2 .}
}
Note this goes two levels deep. For arbitrary levels, it may be best to call the following query until no new triples are created:
CONSTRUCT {
?rsc ?p ?o .
}
WHERE {
?rsc ?p ?o .
}
...where rsc is bound to :A initially and to the values for ?o for subsequent iterations.
It's not possible to get the whole connected graph with one CONSTRUCT query. You'll need to run multiple queries. Even with multiple queries it gets a bit tricky when Blank Nodes are involved as you will have to gradually expand their context and return this context in every subsequent query.
For an example of some code that does exactly this, see: https://github.com/apache/clerezza-rdf-core/tree/master/impl.sparql/src/main/java/org/apache/clerezza/commons/rdf/impl/sparql.

Multiple SELECT query for getting all children of a given root

I want to define the root categories corresponding to interests of users. Then I need to return all other potential interests under given root directory.
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.myweb.com/myontology.owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?user ?othercat
WHERE
{
?othercat rdfs:subClassOf ?root .
{
SELECT ?user ?retailcat ?root
WHERE {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
?retailcat rdfs:subClassOf ?root .
}
}
}
Indeed when I execute the sub-query, it works fine, but it returns current interests of a user, without providing the information of other child-concepts of the same root.
How to solve this issue?
I tried the following query, but it looks like it enters into a loop (the query is executing internally).
There shouldn't be a way for a SPARQL query to enter into a loop. Subqueries are executed first, and then the enclosing query is executed. There's no way to re-execute the inner part or anything like that. (Of course, a query could be expensive and take a long time, but that's not a loop, and is still bounded, in principle.)
As an aside, using owl: as prefix for something other than the standard OWL namespace is somewhat confusing, and likely to mislead other developers when they see your query. There's nothing incorrect about it per se, but you might want to consider using a different prefix for your namespace.
You do have one part of your query that could make things rather expensive. You have the pattern
?entity rdf:type ?type .
?type rdfs:subClassOf* ?retailcat .
where ?entity isn't connected to anything else, and isn't used anywhere else. That means that you'll have a subquery solution for every possible value of ?entity, and that just means you're multiplying the number of results by the number of possible values of ?entity.
If I understand your query, you're trying to go from a user's categories of interest, up the category tree to some root concepts and then find other categories under that root. You don't actually need a subquery for that; you can do it with a non-nested query:
select ?user ?othercat {
?user rdf:type owl:User .
?user owl:hasUserProfile ?userprofile .
?userprofile rdf:type owl:UserProfile .
?userprofile owl:interestedIn ?retailcat .
?retailcat rdfs:subClassOf ?root .
?othercat rdfs:subClassOf ?root .
}
That will find values of ?othercat that are siblings of ?retailcat, along with ?retailcat itself. If you want to avoid ?retailcat, you can add
filter(?othercat != ?retailcat)
but that shouldn't really impact performance much; that's just one result to filter out.
The only other factor that you might want to consider is that you're not really finding a "root" of the category tree with rdfs:subClassOf; you're just going up one level. E.g., if your category tree looks like
Automobile
SUV
SportsCar
Corvette
Mustang
and a user is interested in Mustang, then you'll go up to SportsCar and find Corvette, but you won't be going any farther up the tree. (If you have inference available, you may actually go farther up the tree, but I'm assuming for the moment that you don't.) To follow the subclass links up the tree, you can add * to the path to follow the chain:
?retailcat rdfs:subClassOf* ?root .
?othercat rdfs:subClassOf ?root .
Then you'd get all the classes in the tree (except the very top level one, Automobile).

Stardog rule doesn't trigger

I'm having trouble writing a correct Stardog rule. As I haven't found a way to validate the syntax of the rule, I don't now if it's a syntax or a logical error. Eitherway, the rule doesn't seem to be triggered when reasoning is enabled (reasoning=SL in version 2, reasoning=true in version 3).
#prefix : <http://www.example.org/rules#> .
#prefix rule: <tag:stardog:api:rule:> .
#base <http://www.example.org/rules#> .
[] a rule:SPARQLRule ;
rule:content """
PREFIX : <http://www.example.org/rules#>
PREFIX draft: <http://our/prefix#>
IF {
?x a draft:Obs; draft:has_code ?code .
?z a <http://www.w3.org/ns/sparql#UUID> . // OR: BIND (UUID() AS ?z)
}
THEN {
?z a draft:Code .
?x draft:has_code ?z .
}
""" .
I'm trying to trigger the rule with the following SPARQL query:
PREFIX : <http://our/prefix>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?code
FROM <tag:stardog:api:context:default>
FROM <http://our/graph>
WHERE {
?s rdf:type :Obs .
?obs :has_code ?code .
}
This is likely due to the cyclic nature of the rule. You're inferring :has_code which will in turn be used to fire the rule again, and again, and so forth.
This is a bit easier to visualize when you consider how rules with more than one atom in the header a broken up.

add RDFS inference rules support in endpoint SPARQL

I have create an endpoint SPAQL on OpenLink Virtuoso.
All work well, but i have to access on the data in a Container, in particular a rdf:Seq.
I have a Seq like this:
<myrdf:has_stoptimes>
<rdf:Seq rdf:about="http://test.com/343">
<rdf:li>
<myrdf:StopTime rdf:about="http://test.com/StopTime/434">
...
</ns0:StopTime>
</rdf:li>
<rdf:li>
<myrdf:StopTime rdf:about="http://test.com/StopTime/435">
...
</ns0:StopTime>
</rdf:li>
</rdf:Seq>
Now i see that to access data in a container i can use rdfs:member or FILTER (strstarts(str(?prop), str(rdf:_)) how is explained here
But for my project i have to adopt the first solution because i'm working with Silk and i will use the code syntax like ?a/myrdf:has_stoptimes/rdfs:member without use of "complex" filter.
I have tried to follow this guide but querying the endpoint nothing work how i hoped.
So my question is: how can i query ?a/myrdf:has_stoptimes/rdfs:member on a Virtuoso endpoint SPARQL?Which inference rule i have to add in endpoint SPARQL?
Thank you in advance
UPDATE
I have created the following inference rules in Virtuoso:
ttlp (' #prefix rdfs: .
#prefix rdf: .
rdfs:Container rdf:type rdfs:Class ; rdfs:subClassOf rdfs:Resource .
rdfs:ContainerMembershipProperty a rdfs:Class ; rdfs:subClassOf rdf:Property .
rdf:Seq rdf:type rdfs:Class ; rdfs:subClassOf rdfs:Container .
rdfs:member rdf:type rdf:Property ; rdfs:domain rdfs:Resource ; rdfs:range rdfs:Resource .
', '', 'http://localhost:8890/schema/test') ;
Nothing work querying the SPARQL endpoint like:
define input:inference "http://localhost:8890/schema/property_rules1"
SELECT *
FROM
WHERE {?sep a rdf:Seq.
?seq rdfs:member ?p}
After i tried adding the follow line to the ttl file: rdf:_1 rdfs:subPropertyOf rdfs:member . In this way it work but obviously the results are only for the first element of the container. So is very unconvenient add a line for all of rdf:_n, and i think this is only a temporary solution, it is not correct.
I have tried to add an RDF dump on SILK 2.6.1, and on the section SPARQL of the data source if i run the query:
SELECT *
FROM
WHERE {?sep a rdf:Seq.
?seq rdfs:member ?p}
I obtain the correct result, without specify any inference rules. So i think that in this functionality of SILK there is something that i’m missing in my endpoint SPARQL or am i saying nonsense things?
You can't use variables in property paths, so you can't actually do
?x ?a/has_stoptimes/rdfs:member ?y
Instead, you have to use another variable or blank node in between:
?x ?a ?z . ?z has_stoptimes/rdfs:member ?y
?x ?a [ has_stoptimes/rdfs:member ?y ] .

Sparql to recover the Type of a DBpedia resource

I need a Sparql query to recover the Type of a specific DBpedia resource. Eg.:
pt.DBpedia resource: http://pt.dbpedia.org/resource/Argentina
Expected type: Country (as can be seen at http://pt.dbpedia.org/page/Argentina)
Using pt.DBpedia Sparql Virtuoso Interface (http://pt.dbpedia.org/sparql) I have the query below:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?l ?t where {
?l rdfs:label "Argentina"#pt .
?l rdf:type ?t .
}
But it is not recovering anything, just print the variable names. The virtuoso answer.
Actually I do not need to recover the label (?l) too.
Anyone can fix it, or help me to define the correct query?
http in graph name
I'm not sure how you generated your query string, but when I copy and paste your query into the endpoint and run it, I get results, and the resulting URL looks like:
http://pt.dbpedia.org/sparql?default-graph-uri=http%3A%2F%2Fpt.dbpedia.org&sho...
However, the link in your question is:
http://pt.dbpedia.org/sparql?default-graph-uri=pt.dbpedia.org%2F&should-sponge...
If you look carefully, you'll see that the default-graph-uri parameters are different:
yours: pt.dbpedia.org%2F
mine: http%3A%2F%2Fpt.dbpedia.org
I'm not sure how you got a URL like the one you did, but it's not right; the default-graph-uri needs to be http://pt.dbpedia.org, not pt.dbpedia.org/.
The query is fine
When I run the query you've provided at the endpoint you've linked to, I get the results that I'd expect. It's worth noting that the label here is the literal "Argentina"#pt, and that what you've called ?l is the individual, not the label. The individual ?l has the label "Argentina"#pt.
We can simplify your query a bit, using ?i instead of ?l (to suggest individual):
select ?i ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
When I run this at the Portuguese endpoint, I get these results:
If you don't want the individual in the results, you don't have to select it:
select ?type where {
?i rdfs:label "Argentina"#pt ;
a ?type .
}
or even:
select ?type where {
[ rdfs:label "Argentina"#pt ; a ?type ]
}
If you know the identifier of the resource, and don't need to retrieve it by using its label, you can even just do:
select ?type where {
dbpedia-pt:Argentina a ?type
}
type
==========================================
http://www.w3.org/2002/07/owl#Thing
http://www.opengis.net/gml/_Feature
http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/PopulatedPlace
http://dbpedia.org/ontology/Country
http://schema.org/Place
http://schema.org/Country