Connected to this question (and its previous ones):
Using sh:maxExclusive to compare (the values of) two datatype properties
I created a small ontology with three classes: DataSubject, MemberState, and Minor. There are two datatype properties: has-age and has-minimalage. The former is from DataSubject(s) to integers, the latter is from MemberState(s) to integers. Then there is an object property has-member-state from DataSubject(s) to MemberState(s).
Now we have the following individuals:
ontology:John
rdf:type ontology:DataSubject ;
ontology:has-age "20"^^xsd:positiveInteger ;
ontology:has-member-state ontology:Spain ;
.
ontology:Spain
rdf:type ontology:MemberState ;
ontology:has-minimalage "16"^^xsd:positiveInteger ;
.
And I want to write a SHACL rule saying that each DataSubject whose age is less than the minimal age of his member state is also an individual of the class Minor.
In light of the replies I got to my other questions, I tried:
sh:rule [
rdf:type sh:TripleRule ;
sh:condition [
sh:property [
sh:path ontology:has-age ;
sh:lessThan (ontology:has-member-state ontology:has-minimalage)
] ;
] ;
sh:subject sh:this ;
sh:predicate rdf:type;
sh:object ontology:Minor ;
] ;
Which does not work: it classifies John as Minor, but 20 is not less than 16. Of course I tried many other variants, e.g., "sh:lessThan[sh:node[sh:path (ontology:has-member-state ontology:has-minimalage)];];", many of which do not probably make any sense, but none of them work.
Can someone suggest me how to embed a path in the parameter of sh:lessThan?
I am sorry if I start being annoying with all these questions :-( I am new to SHACL and SPARQL but I am really trying my best to learn them out of all what I can find on the Web.
Thanks
Livio
The official spec is (hopefully) pretty clear that the values must be IRIs, i.e. only direct properties are permitted. You can however try to revert the logic and use a path at the property shape. Otherwise, fall back to SPARQL.
Related
I have an ontology in which each thematic role (e.g., has-agent) is represented via an object property. Furthermore, the inverse property is always defined (e.g., is-agent-of).
I want to assert in the ontology all inverse triples via SHACL rules PROVIDED THAT THEY DO NOT ALREADY EXIST.
Thus, I wrote the following rule:
:assertInverseTriplesOnHasAgent rdf:type sh:NodeShape;
sh:rule [rdf:type sh:TripleRule;
sh:condition
[
sh:not[
sh:property[
sh:path (TBox:has-agent TBox:is-agent-of);
sh:minCount 1;
sh:equals sh:this
]
]
];
sh:subject [sh:path TBox:has-agent];
sh:predicate TBox:is-agent-of;
sh:object sh:this
];
sh:targetSubjectsOf TBox:has-agent.
But it does not work: it asserts the inverse triples even when they already exist (and it shouldn't).
I suspect that "sh:equals sh:this" is not correct, i.e., that "sh:this" cannot be used within sh:property. On the other hand, "sh:minCount 1;" alone does not work because someone can be is-agent-of more than one action.
Can anyone help me? Thanks
I would like to understand how to handle multiple paths and existential quantification in SHACL rules. Let me exemplify my problem with a sample ontology.
The ontology includes the classes "Approve", "Legal", "Result", "Man", and "Machine", all disjoint. It has two properties "has-theme" and "come-from" and the following individuals:
:a rdf:type :Approve ;
:has-theme :r1,:r2 .
:r1 rdf:type :Result ;
:come-from :m1 .
:r2 rdf:type :Result ;
:come-from :m2 .
:m1 rdf:type :Man .
:m2 rdf:type :Machine .
Therefore: the Approve action ":a" has two themes: ":r1" and ":r2". The former comes from the Man ":m1", the latter comes from the Machine ":m2".
I want to write a SHACL rule stating that "Every Approve action having among its themes at least a Result that comes from a Man is Legal".
I tried this, that do NOT classify ":a" as Legal (but it should):
:testRule rdf:type sh:NodeShape;
sh:rule [rdf:type sh:TripleRule;
sh:condition :conditionTest;
sh:subject sh:this;
sh:predicate rdf:type;
sh:object ontology:Legal
];
sh:targetClass ontology:Approve.
:conditionTest
rdf:type sh:NodeShape;
sh:property
[
#IF the theme of the Approve action is a Result come from a Man
sh:path (ontology:has-theme ontology:come-from);
sh:class ontology:Man
].
The problem is that ":a" has two themes, one coming from a Man and the other from a Machine.
Then I read on the Web about sh:oneOrMorePath and I tried the following variants within sh:property:
sh:oneOrMorePath (ontology:has-theme ontology:come-from);
sh:path ([sh:oneOrMorePath ontology:has-theme] ontology:come-from);
sh:path (ontology:has-theme [sh:oneOrMorePath ontology:come-from]);
Nothing to do, these variants don't work either.
On the other hand, if I remove the triple ":r2 :come-from :m2" or the triple ":a :has-theme :r2"
it works, as there is no more in the ontology a branch leading from ":a" to a non-Man.
Could any of you be so kind to help me?
Thank you!
Livio
Your requirements states "having among its themes at least a Result that comes from a Man" which sounds like an existential constraint to me. So you cannot really use sh:class here, but you may rather want to use a qualified value constraint.
I have not tried it, but something like this may work:
:conditionTest
rdf:type sh:NodeShape ;
sh:property [
sh:path (ontology:has-theme ontology:come-from) ;
sh:qualifiedMinCount 1 ;
sh:qualifiedValueShape [
sh:class ontology:Man ;
]
] .
This should mean that at least one of the values of the path has-theme/come-from must conform to the qualified value shape, which means that it must be an instance of Man.
See https://www.w3.org/TR/shacl/#QualifiedValueShapeConstraintComponent for the specification of QVCs in SHACL.
If you can use SHACL-SPARQL and import the dash namespace, you could also simply write dash:hasValueWithClass ontology:Man, see http://datashapes.org/constraints.html#HasValueWithClassConstraintComponent
I have a hierarchy of skos:Concepts and want to define an owl:Class consisting of those individuals that are connected to a specific concept or one of its narrower terms through some property.
I managed to create an owl:Restriction that works for one specific concept, but not for a hierarchy of concepts:
# Concept hierarchy
concepts:Dance a skos:Concept .
concepts:FolkDance a skos:Concept ;
skos:broaderTransitive concepts:Dance .
concepts:SquareDance a skos:Concept ;
skos:broaderTransitive concepts:FolkDance .
# owl axioms
ex:Dance rdfs:subClassOf ex:Movement ;
owl:equivalentClass [
a owl:Restriction ;
owl:onProperty ex:hasKindOfMovement ;
owl:hasValue concepts:Dance
] .
# Assertions
ex:SomeInstance ex:hasKindOfMovement concepts:Dance .
The above correctly makes ex:someInstance an instance of ex:Dance. But how can I make ex:anotherInstance a member of ex:Dance if I have the assertion
ex:anotherInstance ex:hasKindOfMovement concepts:SquareDance
? I. e. where the individual in owl:hasValue is a transitively narrower concept than the one specified in the restriction.
This question seems similar to OWL restrictions - defining classes that only contains properties with a specific property value but I couldn't work it out from there... Any help is much appreciated.
I have a data frame DF which contains numerous variables. Each variable is present twice because I am conducting an analysis of "couples".
Among others, DF has a series of indicators of diversity :
DF$div1.1, DF$div2.1, .... , DF$divN.1, DF$div.1.2, ..., DF$divN.2
Similarly, it has a series of indicators of another characteristic:
DF$char1.1, DF$char2.1, .... , DF$charM.1, DF$char.1.2, ..., DF$charM.2
Here's a link to an example of DF: http://shorttext.com/5d90dd64
Each time the ".1", ".2" stand for the couple member considered.
My goal:
For each indicator divI and charJ, I want to create another variable DF$divchar that takes the value DF$divI.1 when DF$charJ.1>DF$charJ.2; and DF$divI.2 when DF$charJ.1<DF$charJ.2.
Here is the solution I came up with, it seems somehow very intricate and sometimes behaves in strange ways:
I created a series of binary variables that take the value one if DF$charJ.1>DF$charJ.2. The are stored under DF$CharMax.1.
Here's how I created it:
DF$CharMax.1 <- as.data.frame(
sapply(1:length(nam),
function(n)
as.numeric(DF[names(DF)==names.1[n]]
>DF[names(DF)==names.2[n]])
))
I created the function BinaryExtract:
BinaryExtract <- function(var1, var2, extract) {var1*extract +var2*(1-extract)}
I created the matrix NameFull that contains all the possible combinations of div and char, separated with "YY"
NameFull <- sapply(c("div1",...,"divN")
, function(nam) paste(nam, names(DF$YMax.1), sep="YY")
And then I create all my variables:
DF[, as.vector(NameFull)] <- lapply(as.vector(NameFull), function(e)
BinaryExtract(DF[,paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF[, paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF$charMax.1[unlist(strsplit(e,"YY"))[2]]))
My Problem
A. It looks like a very complicated solution for something that simple. What am I missing?
B. Moreover, when I print DF, just typing DF in the command window, I do not see the variables NameFull. They seem to appear with the names of char.
Here's what I get: http://shorttext.com/5d9102c
Similarly, I have tried to change all their names to get rid of the "YY" and it does not seem to work:
names(DF[, as.vector(NameFull)]) <- as.vector(c("div1",...,"divN"), sapply(, function(nam)
paste(nam, names(DF$YMax.1), sep=".")))
When I look at names(DF), I keep getting the old names with the "YY"
However, I do get a result if I explicitly call for them
> DF[,"divIYYcharJ"]
I would really appreciate any suggestion, comment and explanation. I am quite new to R ad was more used to Stata. I feel there is something deeply inefficient here. Thanks
In OWL API, classes may have data properties. For e.g. a class may have a date property hasCommonName "Something". In OWL API, is there any facility like the SQL like which allows querying for classes that hasCommonName containing the word "Some", just like SQL like behave
You can use regular expressions to identify the things you need. Consider the following knowledge base:
DataProperty: hasCommonName
Individual: foo
Facts:
hasCommonName "Something"
You can retrieve the individual foo by using the following class expression: hasCommonName some string[pattern "Some.*"]. The string[pattern "Some.*"] specifies the pattern to be matched. Warning, currently not supported by all reasoners (works for Hermit 1.3.7)
You need to look at some SPARQL tutorials. You can write something like this:
SELECT * WHERE
{
?pizza rdfs:subClassof [
owl:onProperty :hasTopping;
owl:someValuesFrom :TomatoTopping ] .
}
Basically, you need to define the correct predicate based on your restriction.