How do you allow not foreseen properties in RDF when performing Shex validation? - shex

We are creating our Shex definition files checking that some IRIs are of a given type. There is no problem with our generated code but sometimes we get files generated using Protege and most of the individuals are of type X plus owl:NamedIndividual, making our validation fail because now a given resource has 2 assertions of type rdf:type.
Adding owl:NamedIndividual to all shape checks seems like polluting the Shape definition, so how would you allow extra properties that do not conflict with your shape definition?

In Shex, by default the triple constraints are closed which means that a shape like:
:Shape {
rdf:type [ :X ]
}
means that a node that conforms to :Shape must have exactly one rdf:type declaration whose value is :X.
If you want to allow extra values for the rdf:type declaration, you can express it with the keyword EXTRA as:
:Shape EXTRA rdf:type {
rdf:type [ :X ]
}
The meaning now is that a conforming node must have rdf:type :X and can have zero or mode values for rdf:type.
Notice that the previous example could be defined as:
:Shape EXTRA a {
a [ :X ]
}
In the particular case that you only want to allow an extra rdf:type with value owl:NamedIndividual you could also define it as:
:Shape {
a [:X ] ;
a [ owl:NamedIndividual] ;
}
or as:
:Shape {
a [:X owl:NamedIndividual]{2} ;
}

Related

Is there a way to infer existentially quantified statements in OWL?

Consider the following chain of reasoning:
1. Simba is a lion.
2. All lions have at least one parent.
3. So, Simba has at least one parent.
This is a perfectly valid inference, and it can be represented in predicate logic as follows:
s = Simba
L = is a lion
P = is the parent of
1. Ls
2. (Ax)(Lx --> (Ey)(Pxy))
3. (Ey)(Pys)
In a natural deduction system, one would be permitted to infer 3 (via a series of inference rules) from the conjunction of 1 and 2.
I would expect to see a similar inference generated with OWL reasoners. Suppose we had the following triples (using Turtle syntax):
:Simba rdf:type :Lion .
:Lion a owl:Class ;
rdfs:subClassOf
[
a owl:Restriction ;
owl:onProperty :isParentOf ;
owl:someValuesFrom owl:Thing ;
] ;
.
These statements are translations of 1 and 2 into OWL. However, it appears that OWL reasoners do not infer something like 3. Is this right? Or can something like this inference be made using OWL reasoners?

What is the correct way of validating RDF with Shex when part of the IRIs are in the Triple Store?

Say that I want to validate insertion of a company promotion in a triple Store using Shex. A possible approach would be to code Shex as in:
:Promotion {
my-onto:has_person #:Person ;
my-onto:grants_role #:Role ;
}
:Person {
a [ foaf:Person ] ;
}
:Role {
a [ my-onto:CompanyRole ] ;
}
This is a simplification. The problem is that when inserting the data the triple will be something of:
:promotion-123 my-onto:has_person :person-456 ;
my-onto:grants_role :role-CTO .
and this graph won't pass Shex validation because it lacks all the a triples.
So for defining and documenting what are correct as IRIs in the two relations, it makes sense to have the Shapes but in 90% of all real world scenarios data will come as in the example above without the type (in this example) relation and thus will fail to validate.
What would the correct way of documenting complex and nested shapes for validating RDF but at the same time "disable" some checks a certain points in the graph?
The use case I'm thinking about is when I need to add extra info to "shapes" already existing, using IRIs like owl:NamedIndividuals or constants in an ontology, already existing entities like Persons, companies, etc.
You mean that you insert data without rdf:type (a) declarations and the system adds those declarations by some kind of reasoning system.
ShEx doesn't interfere with reasoning systems and doesn't treat rdf:type declarations in any special way. So there could be several approaches for that use case.
One approach is to have add a question mark to the rdf:type declaration as:
:Promotion {
my-onto:has_person #:Person ;
my-onto:grants_role #:Role ;
}
:Person {
a [ foaf:Person ] ? ;
}
:Role {
a [ my-onto:CompanyRole ] ? ;
}
which says that a :Person can either not have a rdf:type declaration or if it has a rdf:type declaration, then it must contain the single value foaf:Person.
Another approach could be to have two shapes, one before reasoning to check the input data and another after insertion the data to check the correct behaviour of the insertion process.
Notice that it is possible to have different shapes for the same data that act at different points during the data processing pipeline.

Necessary and Sufficient Property Restrictions in OWL

So I was reading this and it says:
As an example of a necessary and sufficient condition, take a look at
the following definition:
:RedThing a owl:Class ; owl:equivalentClass
[ a owl:Restriction ;
owl:onProperty :color ;
owl:hasValue red^^<http://www.w3.org/2001/XMLSchema#string>
]
What I interpret this to mean is that if something is red, then that thing must be a RedThing.Also, if something is a RedThing, then it must be the color red.
When I added this code snippet to Protege, and I write:
:test_subject :color red^^<http://www.w3.org/2001/XMLSchema#string>
Then the following is inferred by the reasoner:
:test_subject rdf:type :RedThing
What this covers is the necessary part of the restriction definition, i.e. if something is red, then that thing must be a RedThing.
When I add the following to an ontology (again using Protege):
test_subject_2 rdf:type :RedThing
Then the following SHOULD be inferred by the reasoner:
:test_subject_2 :color red^^<http://www.w3.org/2001/XMLSchema#string>
Because this is the sufficient part of the condition. i.e if something is a RedThing, then it must be the color red.
BUT it is NOT inferred. What am I missing here?

Blank nodes in class definition for enforcing identity

I hope the question is not trivial, I spent a decent amount of time looking for an answer around.
I am creating an ontology in OWL and I've been trying to enforce a particular constraint into a class description but not being able to do it with the tools provided by OWL and resorted to blank nodes as existential variables in the description of the class. Protege5 did not like it a bit.
I'd like to model classes of spaces and movements from one space to another, and in particular I'd like to model a movement that has as a target the same space as the starting space.
In logic I'd describe my InternalMovement class as:
InternalMovement = forall ?x exist ?y (Movement(?x) ^ space(?x,?y) ^ direction(?x,?y))
In OWL variables do not exist and enforcing the identity of a blank nodes throughout a class description doesn't seem possible. I resorted to blank nodes because they should be treated as existential variables and I hope using blank nodes ids would do the trick. I was wrong and I don't know how to model this simple class.
The Turtle snippet is this:
:Movement rdf:type owl:Class .
:Space rdf:type owl:Class .
:direction rdf:type owl:FunctionalProperty ,
owl:ObjectProperty ;
rdfs:domain :Movement ;
rdfs:range :Space .
:space rdf:type owl:FunctionalProperty ,
owl:ObjectProperty ;
rdfs:domain :Movement ;
rdfs:range :Space .
:InternalMovement rdf:type owl:Class ;
owl:equivalentClass [ rdf:type owl:Class ;
owl:intersectionOf ( :Movement
[ rdf:type owl:Restriction ;
owl:onProperty :space ;
owl:hasValue _:sp1
]
[ rdf:type owl:Restriction ;
owl:onProperty :target ;
owl:hasValue _:sp1
]
)
] .
I would expect that the following individual would be classified as InternalMovement, but obviously it doesn't.
:internalmovement rdf:type :Movement ,
:space :room1 ;
:direction :room1 .
:room1 rdf:type :Space.
Can anyone help me, please?
Thanks
It sounds like what you want is to define a class by specifying that it has the same value for two particular properties. If OWL supported property intersection (some description logics do), then you could write
InternalMovement ≡ ∃(space &sqcap; direction)
Unfortunately, OWL doesn't have this. However, you could define a property that is a subproperty of both space and target and use that. That is:
spaceAndDirection &sqsubseteq; space
spaceAndDirection &sqsubseteq; target
InternalMovement ≡ ∃spaceAndDirection
This means that if x is an InternalMovement, then there exists a y such that spaceAndDirection(x,y), and then from the subproperty axioms, we may infer space(x,y) and direction(x,y).
That will take care of some of what you want, but not all of it. If you just know that some movement x has some y as a space and as a direction, you still can't infer spaceAndDirection(x,y), and so you can't infer that x is an InternalMovement.
If you add cardinality axioms that a movement has exactly one space and exactly one direction, then you can ensure that if x has y as its space and direction, then if it has a spaceAndDirection value, then that value must be y.
If you also add the (min or exact) cardinality axiom that InternalMovement has (at least or exactly) one spaceAndDirection value, then if x is an InternalModement, then from any two of the following, you can infer the third:
space(x,y)
Since x is an InternalMovement, it must have a spaceAndDirection value. Call it z. Then spaceAndDirection(x,z). Then, since spaceAndDirection is a subproperty of space and direction, we also have space(x,z) and direction(x,z). Since x is a Movement, it has exactly one space value, so y = z. Then we also have direction(x,y) and spaceAndDirection(x,y).
direction(x,y)
Analogous to above.
spaceAndDirection(x,y)
Since spaceAndDirection is a subproperty of space and direction, we immediately have space(x,y) and direction(x,y).

How to call a constructed quotation in Factor

I have a word which constructs a quotation which I want to be called. However, when I load the code I get Cannot apply “call” to a run-time computed value. If I use the walker and step thru the code it executes as expected. How are you supposed to call a constructed quotation?
: ba>struct ( array class -- struct array )
[ <struct> swap ] keep struct-slots
[
[ type>> to-type ] keep
name>> setter-word 1quotation curry
[ over ] dip curry call drop
] each
;
EDITED: This does work
: ba>struct ( array class -- struct array )
[ <struct> swap ] keep struct-slots
[
[ type>> to-type ] keep
name>> setter-word 1quotation curry
[ over ] dip curry call( -- x ) drop
] each
;
The problem stems from the runtime not knowing what the stack effect is of a constructed quote. In these cases, you must declare what the stack looks like to the quote for the call.

Resources