Select single ontology class and all of its axioms and annotations as a subset - sparql

Is there a SPARQL or other method to extract a single class and all of its associated axioms and annotations from an ontology? For example, assume one had a list of classes from one ontology that they wanted to add to another ontology.
For example, consider the following class from IDO: http://purl.obolibrary.org/obo/IDO_0000406 (see below). In this example, it might be easier to simply parse the contents of the ontology's OWL file using a regex pattern such as /(<owl:Class .+?\s\s\s\s\s\n<\/owl:Class>/ to capture all of the details of every class after which the classes of interest could simply be filtered out and appended to a new OWL file.
<owl:Class rdf:about="http://purl.obolibrary.org/obo/IDO_...">
...
</owl:Class>
...
<owl:Class rdf:about="http://purl.obolibrary.org/obo/IDO_0000406">
<rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/IDO_0000452"/>
<rdfs:subClassOf>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/RO_0000052"/>
<owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/OBI_0100026"/>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000054"/>
<owl:allValuesFrom>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://purl.obolibrary.org/obo/BFO_0000015"/>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
<owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/IDO_0000625"/>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
<owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/TRANS_0000000"/>
</owl:Restriction>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
<owl:someValuesFrom>
<owl:Class>
<owl:intersectionOf rdf:parseType="Collection">
<rdf:Description rdf:about="http://purl.obolibrary.org/obo/IDO_0000626"/>
<owl:Class>
<owl:complementOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000066"/>
<owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/IDO_0000457"/>
</owl:Restriction>
</owl:complementOf>
</owl:Class>
</owl:intersectionOf>
</owl:Class>
</owl:someValuesFrom>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</owl:allValuesFrom>
</owl:Restriction>
</owl:intersectionOf>
</owl:Class>
</rdfs:subClassOf>
<obo:IAO_0000115 xml:lang="en">An infectious disposition to become part of a disorder only in organisms whose defenses are compromised.</obo:IAO_0000115>
<obo:IAO_0000117>Albert Goldfain</obo:IAO_0000117>
<obo:IAO_0000117>Alexander Diehl</obo:IAO_0000117>
<obo:IAO_0000117>Lindsay Cowell</obo:IAO_0000117>
<obo:IAO_0000118 xml:lang="en">opportunitistic pathogenic disposition</obo:IAO_0000118>
<rdfs:comment>The disposition is realized in a process by which the bearer becomes part of a disorder in an immunocompromised host.</rdfs:comment>
<rdfs:comment xml:lang="en">This includes individuals who are immunocompromised or who have damaged barriers that normally protect against infection (e.g. skin).</rdfs:comment>
<rdfs:label xml:lang="en">opportunistic infectious disposition</rdfs:label>
</owl:Class>
EDIT: I tried using rdflib to achieve this by loading the source ontology as a Graph(). Using a for loop to iterate through statements in the loaded graph, it's easy enough to find the triples which are directly connected to a class, say, ido:IDO_0000406 -> obo:IAO_0000117 -> Alexander Diehl. These can then be added to the target ontology, which is also loaded as a graph. However, using the IDO_0000406 class example, it is clear that triples not on the first sub-level (i.e. anything within the clause <rdfs:subClassOf><owl:Class>...) will not come through as expected. For example:
g_tgt = Graph()
classes = ['http://purl.obolibrary.org/obo/IDO_0000406'
'http://purl.obolibrary.org/obo/IDO_0000407',
'http://purl.obolibrary.org/obo/IDO_0000408',
'http://purl.obolibrary.org/obo/IDO_0000409']
g_src = Graph()
g_src.parse('ido.owl')
for stmt in g_src: # stmt: (subject, predicate, object)
if str(stmt[0]) in classes:
# adds all first-level triples to target graph
g_tgt.add((stmt[0], stmt[1], stmt[2]))
My thought is to approach non-first-level nodes in a recursive fashion and will update if this is successful.
EDIT 2: It should be possible to extract the classes using ROBOT (http://robot.obolibrary.org/extract). For example:
robot extract --method STAR \
--input filtered.owl \
--term-file uberon_module.txt \
--output results/uberon_module.owl
where uberon_module.txt would include the list of classes to be extracted.

Related

Is there a way to query using SPARQL for more than one value of object when the subject and predicate are the same?

For context I am using GraphDB (SPARQL 1.1), and I have extended the What To Make ontology. I'd like to construct a query that can select ONLY the subjects that contain all of the objects with matching values for a particular predicate.
In my data (below) selecting the individual &so;KitchenDrawer's so:contains predicates and matching those against only those '&wtm;Recipe''s that contain just the values for wtm:hasIngredient. The subject and predicate are the same but there are alternating objects.
When I run the query (with &so;KitchenDrawer only containing &ind;Basil and &ind;Tomato), I would like to only get the subject's &ind;JustTomatoAndBasil and &ind;JustTomato, omitting &ind;Pesto as it has ingredients other than basil and tomato.
RDF Data:
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY dct "http://purl.org/dc/terms/" >
<!ENTITY obo "http://purl.obolibrary.org/obo/" >
<!ENTITY skos "http://www.w3.org/2004/02/skos/core#" >
<!ENTITY wtm "http://purl.org/heals/food/" >
<!ENTITY ind "http://purl.org/heals/ingredient/" >
<!ENTITY prov "http://www.w3.org/ns/prov#">
<!ENTITY sm "http://www.omg.org/techprocess/ab/SpecificationMetadata/">
<!ENTITY so "http://example.com/storage-ontology/">
]>
<rdf:RDF xml:base="http://purl.org/heals/ingredient/"
xmlns:so="http://example.com/storage-ontology/"
xmlns:wtm="http://purl.org/heals/food/"
xmlns:dct="http://purl.org/dc/terms/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:skos="http://www.w3.org/2004/02/skos/core#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:obo="http://purl.obolibrary.org/obo/"
xmlns:prov="http://www.w3.org/ns/prov#"
xmlns:ind="http://purl.org/heals/ingredient/"
xmlns:sm="https://www.omg.org/techprocess/ab/SpecificationMetadata/">
<owl:Ontology rdf:about="http://purl.org/heals/ingredient/">
<owl:imports rdf:resource="http://purl.org/heals/food/"/>
<owl:imports rdf:resource="http://www.omg.org/techprocess/ab/SpecificationMetadata/"/>
<rdfs:label>What to Make Individuals Extensions</rdfs:label>
<dct:license rdf:datatype="&xsd;anyURI">http://opensource.org/licenses/MIT</dct:license>
</owl:Ontology>
<owl:NamedIndividual rdf:about="&ind;JustTomato">
<rdf:type rdf:resource="&wtm;Recipe"/>
<wtm:hasIngredient rdf:resource="&ind;Tomato"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Lunch"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Dinner"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Snack"/>
<skos:scopeNote>recipe</skos:scopeNote>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="&ind;JustTomatoAndBasil">
<rdf:type rdf:resource="&wtm;Recipe"/>
<wtm:hasIngredient rdf:resource="&ind;Tomato"/>
<wtm:hasIngredient rdf:resource="&ind;Basil"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Lunch"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Dinner"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Snack"/>
<skos:scopeNote>recipe</skos:scopeNote>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="&ind;Pesto">
<rdf:type rdf:resource="&wtm;Recipe"/>
<wtm:hasIngredient rdf:resource="&ind;Basil"/>
<wtm:hasIngredient rdf:resource="&ind;PineNuts"/>
<wtm:hasIngredient rdf:resource="&ind;Parmesan"/>
<wtm:hasIngredient rdf:resource="&ind;Garlic"/>
<wtm:hasIngredient rdf:resource="&ind;OliveOil"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Lunch"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Dinner"/>
<wtm:isRecommendedForMeal rdf:resource="&wtm;Snack"/>
<wtm:serves rdf:datatype="&xsd;integer">4</wtm:serves>
<rdfs:label>basil pesto</rdfs:label>
<skos:definition>a traditional pesto made from paresan cheese and basil</skos:definition>
<skos:scopeNote>recipe</skos:scopeNote>
</owl:NamedIndividual>
<owl:Class rdf:about="&so;StorageLocation">
</owl:Class>
<owl:Class rdf:about="&so;Drawer">
<rdfs:subClassOf rdf:resource="&so;StorageLocation"/>
</owl:Class>
<owl:ObjectProperty rdf:about="&so;contains">
</owl:ObjectProperty>
<owl:NamedIndividual rdf:about="&so;KitchenDrawer">
<rdf:type rdf:resource="&so;Rack"/>
<so:contains rdf:resource="&ind;Basil"></so:contains>
<so:contains rdf:resource="&ind;Tomato"></so:contains>
</owl:NamedIndividual>
</rdf:RDF>

Using the SPARQL Query tab in Protoge to query elements within my own ontology

I have an ontology that I am trying to qrite SPARQL queries for.
I'm using the Ontology IRI (http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology) displayed on the Active ontology tab to define the PREFIX value in the query below:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX chris: <http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#>
SELECT ?class ?activity
WHERE { ?class chris:hasActivity ?activity }
When I run this nothing is returned, yet when I output the ontology into RDF format I can see instances if what I want to be returned:
<owl:Class rdf:about="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#SportsHallBooking">
<rdfs:subClassOf rdf:resource="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#BookableTimetable"/>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#hasActivity"/>
<owl:someValuesFrom rdf:resource="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#Badminton"/>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#hasActivity"/>
<owl:someValuesFrom rdf:resource="http://www.semanticweb.org/chris/ontologies/2020/2/dis-coursework-ontology#Football"/>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>
So I would expect the results to include:
class | activity SportsHallBooking | Badminton
SportsHallBooking | Football
Yet I get nothing back.
Credit to Stanislav for the answer.
select * { ?class rdfs:subClassOf [ owl:onProperty chris:hasActivity; owl:someValuesFrom ?activity ] }

Fusuki: Not able to upload owl file

While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
Result: failed with message "SyntaxError: Unexpected token < in JSON at position 0"]2]2
and my .owl file is
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#">
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY ns_transport "file://www.ibm.com/WSRR/Transport#">
<!ENTITY wsrr "http://www.ibm.com/xmlns/prod/serviceregistry/6/1/model#">
]>
<rdf:RDF
xmlns:xsd="&xsd;"
xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:owl="&owl;"
xmlns:ns_transport="&ns_transport;"
xmlns:wsrr="&wsrr;"
>
<owl:Ontology rdf:about="&ns_transport;TransportOntology">
<owl:imports rdf:resource="http://www.ibm.com/xmlns/prod/serviceregistry/6/1/model"/>
<wsrr:prefix rdf:datatype="http://www.w3.org/2001/XMLSchema#string">transport</wsrr:prefix>
<rdfs:label>A transport classification system.</rdfs:label>
<rdfs:comment>Cars and buses and some superclasses.</rdfs:comment>
</owl:Ontology>
<owl:Class rdf:about="&ns_transport;Transport">
<rdfs:label>Transport</rdfs:label>
<rdfs:comment>Top-level root class for transport.</rdfs:comment>
</owl:Class>
<owl:Class rdf:about="&ns_transport;LandTransport">
<rdfs:subClassOf rdf:resource="&ns_transport;Transport"/>
<rdfs:label>Land Transport.</rdfs:label>
<rdfs:comment>Middle-level land transport class.</rdfs:comment>
</owl:Class>
<owl:Class rdf:about="&ns_transport;AirTransport">
<rdfs:subClassOf rdf:resource="&ns_transport;Transport"/>
<rdfs:label>Air Transport.</rdfs:label>
<rdfs:comment>Middle-level air transport class.</rdfs:comment>
</owl:Class>
<owl:Class rdf:about="&ns_transport;Bus">
<rdfs:subClassOf rdf:resource="&ns_transport;LandTransport"/>
<rdfs:label>Bus.</rdfs:label>
<rdfs:comment>Bottom-level bus class.</rdfs:comment>
</owl:Class>
<owl:Class rdf:about="&ns_transport;Car">
<rdfs:subClassOf rdf:resource="&ns_transport;LandTransport"/>
<rdfs:label>Car.</rdfs:label>
<rdfs:comment>Bottom-level car class.</rdfs:comment>
</owl:Class>
</rdf:RDF>
While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
While uploading .owl file to fusuki server I'm getting errror saying
2.1kb
I had the same problem in apache-jena-fuseki-3.5.0 version, but this error has handled in apache-jena-fuseki-3.6.0

How can I create an owl:intersectionOf two owl:Classes?

For a school exercise, I have an RDF file and an OWL file.
There is an owl:Class Lecturer and an owl:Class Researcher. The intersection of both should be a Professor. I have put my RDF and OWL file below.
Problem is: when I do my query, no resource is of type Professor, while in the RDF file we can see that Laura should be a Professor.
Reduced version of rdf file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rdf:RDF [
<!ENTITY humans "http://www.inria.fr/2007/09/11/humans.rdfs">
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#"> ]>
<rdf:RDF
xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:xsd ="&xsd;"
xmlns ="&humans;#"
xml:base ="&humans;-instances" >
<Person rdf:ID="Laura">
<name>Laura</name>
</Person>
<Lecturer rdf:about="#Laura"/>
<Researcher rdf:about="#Laura">
<name>Laura</name>
</Researcher>
</rdf:RDF>
Reduced version of owl file:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns="http://www.w3.org/2000/01/rdf-schema#"
xml:base="http://www.inria.fr/2007/09/11/humans.rdfs"
xmlns:owl="http://www.w3.org/2002/07/owl#">
<owl:Class rdf:ID="Person">
</owl:Class>
<owl:Class rdf:ID="Lecturer">
<subClassOf rdf:resource="#Person"/>
</owl:Class>
<owl:Class rdf:ID="Researcher">
<subClassOf rdf:resource="#Person"/>
</owl:Class>
<owl:Class rdf:id="Professor">
<owl:intersectionOf rdf:parseType="Collection">
<owl:Class rdf:about="#Lecturer"/>
<owl:Class rdf:about="#Researcher"/>
</owl:intersectionOf>
</owl:Class>
</rdf:RDF>
The query I used was the defautl query:
select * where {
?x ?p ?y
}
But what I actually would expect to do is the following:
select * where {
?x a <http://www.inria.fr/2007/09/11/humans.rdfs#Professor>
}
I did look at this answer: Why do we need to use rdf:parseType="Collection" with owl:intersectionOf? but I don't understand in which way it should be used for my specific problem.
I hope somebody can help. By the way, it's my first post here, so let me know if something's missing.
Paraphrased from comments by #stanislav-kralin:
Use correct capitalization of rdf:ID (not rdf:id), and enable "OWL-Max" reasoning when loading your RDF into GraphDB.

XACML Bags operations

Assume we have a bag of booleans. Is there a function that can tell whether the number of "true" values is larger than some constant (e.g., 5)?
I came across "n-of" function, but it requires multiple separate attributes as an input and not a bag... Maybe "map" function can help, but not sure how since I didn't find a function that can reduce the number of items in a bag.
Thanks!
Michael.
To achieve what you are looking for, you need to use two functions:
a function that measures the size of the bag e.g. booleanBagSize(someAttribute)
a functiont that checks that each value of the bag is equal to true. e.g. booleanEquals used in conjunction with a higher-order function e.g. AllOf
The resulting code in ALFA would be:
namespace axiomatics{
attribute allowed{
category = subjectCat
id = "axiomatics.allowed"
type = boolean
}
policy allowIf5True{
apply firstApplicable
rule allow{
permit
condition booleanBagSize(allowed)>5 && allOf(function[booleanEqual], true, allowed)
}
}
}
And the XACML 3.0 output would be
<?xml version="1.0" encoding="UTF-8"?>
<!--This file was generated by the ALFA Plugin for Eclipse from Axiomatics AB (http://www.axiomatics.com).
Any modification to this file will be lost upon recompilation of the source ALFA file-->
<xacml3:Policy xmlns:xacml3="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17"
PolicyId="http://axiomatics.com/alfa/identifier/axiomatics.allowIf5True"
RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:first-applicable"
Version="1.0">
<xacml3:Description />
<xacml3:PolicyDefaults>
<xacml3:XPathVersion>http://www.w3.org/TR/1999/REC-xpath-19991116</xacml3:XPathVersion>
</xacml3:PolicyDefaults>
<xacml3:Target />
<xacml3:Rule
Effect="Permit"
RuleId="http://axiomatics.com/alfa/identifier/axiomatics.allowIf5True.allow">
<xacml3:Description />
<xacml3:Target />
<xacml3:Condition>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than">
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-bag-size" >
<xacml3:AttributeDesignator
AttributeId="axiomatics.allowed"
DataType="http://www.w3.org/2001/XMLSchema#boolean"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Apply>
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#integer">5</xacml3:AttributeValue>
</xacml3:Apply>
<xacml3:Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:all-of" >
<xacml3:Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:boolean-equal"/>
<xacml3:AttributeValue
DataType="http://www.w3.org/2001/XMLSchema#boolean">true</xacml3:AttributeValue>
<xacml3:AttributeDesignator
AttributeId="axiomatics.allowed"
DataType="http://www.w3.org/2001/XMLSchema#boolean"
Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"
MustBePresent="false"
/>
</xacml3:Apply>
</xacml3:Apply>
</xacml3:Condition>
</xacml3:Rule>
</xacml3:Policy>
This approach only works if the bag only contains true values.