From 630705a8fe7ae64edbc8452036a125513256f078 Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Fri, 14 Sep 2012 22:49:29 -0700 Subject: [PATCH] Start implementing infering triples. This includes utilities to import the common schemas, and a bit of functionality for validating models, in addition to the rule to compute inverseOf. --- MANIFEST.in | 1 + encode_submission/encode_find.py | 8 +- encode_submission/submission_report.py | 9 +- htsworkflow/util/rdfhelp.py | 73 +++- htsworkflow/util/rdfinfer.py | 156 +++++++ htsworkflow/util/rdfns.py | 25 ++ htsworkflow/util/schemas/dc.turtle | 28 ++ htsworkflow/util/schemas/owl.turtle | 556 +++++++++++++++++++++++++ htsworkflow/util/schemas/rdf.turtle | 258 ++++++++++++ htsworkflow/util/schemas/rdfs.turtle | 130 ++++++ htsworkflow/util/test/test_rdfhelp.py | 37 ++ htsworkflow/util/test/test_rdfinfer.py | 183 ++++++++ setup.py | 19 +- 13 files changed, 1436 insertions(+), 47 deletions(-) create mode 100644 htsworkflow/util/rdfinfer.py create mode 100644 htsworkflow/util/rdfns.py create mode 100644 htsworkflow/util/schemas/dc.turtle create mode 100644 htsworkflow/util/schemas/owl.turtle create mode 100644 htsworkflow/util/schemas/rdf.turtle create mode 100644 htsworkflow/util/schemas/rdfs.turtle create mode 100644 htsworkflow/util/test/test_rdfinfer.py diff --git a/MANIFEST.in b/MANIFEST.in index c96b250..83c439d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,3 @@ include RELEASE-VERSION include version.py +include htsworkflow/util/schemas/*.turtle diff --git a/encode_submission/encode_find.py b/encode_submission/encode_find.py index 0495d14..7589f54 100644 --- a/encode_submission/encode_find.py +++ b/encode_submission/encode_find.py @@ -26,18 +26,14 @@ if not 'DJANGO_SETTINGS_MODULE' in os.environ: from htsworkflow.submission import daf, ucsc from htsworkflow.util import api +from htsworkflow.util.rdfns import * from htsworkflow.util.rdfhelp import \ - dafTermOntology, \ - dublinCoreNS, \ get_model, \ get_serializer, \ sparql_query, \ submissionOntology, \ libraryOntology, \ - load_into_model, \ - rdfNS, \ - rdfsNS, \ - xsdNS + load_into_model TYPE_N = rdfNS['type'] CREATION_DATE = libraryOntology['date'] diff --git a/encode_submission/submission_report.py b/encode_submission/submission_report.py index 3f55479..d8ace39 100644 --- a/encode_submission/submission_report.py +++ b/encode_submission/submission_report.py @@ -4,17 +4,12 @@ import jinja2 from pprint import pprint from htsworkflow.util.rdfhelp import \ - dafTermOntology, \ - dublinCoreNS, \ get_model, \ get_serializer, \ sparql_query, \ - submissionOntology, \ libraryOntology, \ - load_into_model, \ - rdfNS, \ - rdfsNS, \ - xsdNS + load_into_model +from htsworkflow.util.rdfns import * TYPE_N = rdfNS['type'] CREATION_DATE = libraryOntology['date'] diff --git a/htsworkflow/util/rdfhelp.py b/htsworkflow/util/rdfhelp.py index 7f8902a..fda8772 100644 --- a/htsworkflow/util/rdfhelp.py +++ b/htsworkflow/util/rdfhelp.py @@ -2,6 +2,7 @@ """ import collections from datetime import datetime +from glob import glob from urlparse import urlparse, urlunparse from urllib2 import urlopen import logging @@ -14,27 +15,14 @@ import RDF logger = logging.getLogger(__name__) -# standard ontology namespaces -owlNS = RDF.NS('http://www.w3.org/2002/07/owl#') -dublinCoreNS = RDF.NS("http://purl.org/dc/elements/1.1/") -rdfNS = RDF.NS("http://www.w3.org/1999/02/22-rdf-syntax-ns#") -rdfsNS = RDF.NS("http://www.w3.org/2000/01/rdf-schema#") -xsdNS = RDF.NS("http://www.w3.org/2001/XMLSchema#") - -# internal ontologies -submissionOntology = RDF.NS( - "http://jumpgate.caltech.edu/wiki/UcscSubmissionOntology#") -dafTermOntology = RDF.NS("http://jumpgate.caltech.edu/wiki/UcscDaf#") -libraryOntology = RDF.NS("http://jumpgate.caltech.edu/wiki/LibraryOntology#") -inventoryOntology = RDF.NS( - "http://jumpgate.caltech.edu/wiki/InventoryOntology#") -submissionLog = RDF.NS("http://jumpgate.caltech.edu/wiki/SubmissionsLog/") -geoSoftNS = RDF.NS('http://www.ncbi.nlm.nih.gov/geo/info/soft2.html#') +from htsworkflow.util.rdfns import * + +SCHEMAS_URL='http://jumpgate.caltech.edu/phony/schemas' +INFERENCE_URL='http://jumpgate.caltech.edu/phony/inference' ISOFORMAT_MS = "%Y-%m-%dT%H:%M:%S.%f" ISOFORMAT_SHORT = "%Y-%m-%dT%H:%M:%S" - def sparql_query(model, query_filename, output_format='text'): """Execute sparql query from file """ @@ -245,10 +233,10 @@ def get_model(model_name=None, directory=None): directory = os.getcwd() if model_name is None: - storage = RDF.MemoryStorage() + storage = RDF.MemoryStorage(options_string="contexts='yes'") logger.info("Using RDF Memory model") else: - options = "hash-type='bdb',dir='{0}'".format(directory) + options = "contexts='yes',hash-type='bdb',dir='{0}'".format(directory) storage = RDF.HashStorage(model_name, options=options) logger.info("Using {0} with options {1}".format(model_name, options)) @@ -299,6 +287,7 @@ def load_string_into_model(model, parser_name, data, ns=None): for s in rdf_parser.parse_string_as_stream(data, ns): conditionally_add_statement(model, s, ns) + def fixup_namespace(ns): if ns is None: ns = RDF.Uri("http://localhost/") @@ -309,6 +298,7 @@ def fixup_namespace(ns): raise ValueError(errmsg.format(str(type(ns)))) return ns + def conditionally_add_statement(model, s, ns): imports = owlNS['imports'] if s.predicate == imports: @@ -321,6 +311,45 @@ def conditionally_add_statement(model, s, ns): s.object = sanitize_literal(s.object) model.add_statement(s) + +def add_default_schemas(model, schema_path=None): + """Add default schemas to a model + Looks for turtle files in either htsworkflow/util/schemas + or in the list of directories provided in schema_path + """ + + if schema_path is None: + path, _ = os.path.split(__file__) + schema_path = [os.path.join(path, 'schemas')] + elif type(schema_path) in types.StringTypes: + schema_path = [schema_path] + + for p in schema_path: + for f in glob(os.path.join(p, '*.turtle')): + add_schema(model, f) + +def add_schema(model, filename): + """Add a schema to a model. + + Main difference from 'load_into_model' is it tags it with + a RDFlib context so I can remove them later. + """ + parser = RDF.Parser(name='turtle') + context = RDF.Node(RDF.Uri(SCHEMAS_URL)) + url = 'file://' + filename + for s in parser.parse_as_stream(url): + try: + model.append(s, context) + except RDF.RedlandError as e: + logger.error("%s with %s", str(e), str(s)) + + +def remove_schemas(model): + """Remove statements labeled with our schema context""" + context = RDF.Node(RDF.Uri(SCHEMAS_URL)) + model.context_remove_statements(context) + + def sanitize_literal(node): """Clean up a literal string """ @@ -373,10 +402,14 @@ def get_serializer(name='turtle'): """ writer = RDF.Serializer(name=name) # really standard stuff - writer.set_namespace('owl', owlNS._prefix) writer.set_namespace('rdf', rdfNS._prefix) writer.set_namespace('rdfs', rdfsNS._prefix) + writer.set_namespace('owl', owlNS._prefix) + writer.set_namespace('dc', dcNS._prefix) + writer.set_namespace('xml', xmlNS._prefix) writer.set_namespace('xsd', xsdNS._prefix) + writer.set_namespace('vs', vsNS._prefix) + writer.set_namespace('wot', wotNS._prefix) # should these be here, kind of specific to an application writer.set_namespace('libraryOntology', libraryOntology._prefix) diff --git a/htsworkflow/util/rdfinfer.py b/htsworkflow/util/rdfinfer.py new file mode 100644 index 0000000..221063f --- /dev/null +++ b/htsworkflow/util/rdfinfer.py @@ -0,0 +1,156 @@ +import RDF + +from htsworkflow.util.rdfns import * +from htsworkflow.util.rdfhelp import SCHEMAS_URL + +INFER_URL='http://jumpgate.caltech.edu/phony/infer' + +class Infer(object): + """Provide some simple inference. + + Provides a few default rules as methods starting with _rule_ + """ + def __init__(self, model): + self.model = model + self._context = RDF.Node(RDF.Uri(INFER_URL)) + + + def update(self, max_iterations=None): + """Update model with with inferred statements. + + max_iterations puts a limit on the number of times we + run through the loop. + + it will also try to exit if nothing new has been inferred. + + Also this is the naive solution. + There's probably better ones out there. + """ + iterations = 0 + while max_iterations is None or iterations != max_iterations: + starting_size = self.model.size() + + for method_name in dir(self): + if method_name.startswith('_rule_'): + method = getattr(self, method_name) + method() + if self.model.size() == starting_size: + # we didn't add anything new + return + + def _rule_inverse_of(self): + """Add statements computed with inverseOf + """ + body = """ + prefix rdf: + prefix rdfs: + prefix owl: + + select ?o ?reverse ?s + where { + ?s ?term ?o . + ?s a ?subject_type . + ?o a ?object_type . + ?term owl:inverseOf ?reverse . + ?term rdfs:domain ?subject_type ; + rdfs:range ?object_type . + ?reverse rdfs:domain ?object_type ; + rdfs:range ?subject_type . + }""" + query = RDF.SPARQLQuery(body) + + statements = [] + for r in query.execute(self.model): + s = RDF.Statement(r['o'], r['reverse'], r['s']) + if s not in self.model: + self.model.append(s, self._context) + + + def _validate_types(self): + body = """ + prefix rdf: + prefix rdfs: + prefix owl: + + select ?subject ?predicate ?object + where { + ?subject ?predicate ?object + OPTIONAL { ?subject a ?class } + FILTER(!bound(?class)) + } + """ + query = RDF.SPARQLQuery(body) + errmsg = "Missing type for: {0}" + for r in query.execute(self.model): + yield errmsg.format(str(r['subject'])) + + def _validate_undefined_properties(self): + """Find properties that aren't defined. + """ + body = """ + prefix rdf: + prefix rdfs: + prefix owl: + + select ?subject ?predicate ?object + where { + ?subject ?predicate ?object + OPTIONAL { ?predicate a ?predicate_class } + FILTER(!bound(?predicate_class)) + }""" + query = RDF.SPARQLQuery(body) + msg = "Undefined property in {0} {1} {2}" + for r in query.execute(self.model): + yield msg.format(str(r['subject']), + str(r['predicate']), + str(r['object'])) + + def _validate_property_types(self): + """Find resources that don't have a type + """ + property_template = """ + prefix rdf: + prefix rdfs: + + select ?type + where {{ + <{predicate}> a rdf:Property ; + {space} ?type . + }}""" + + wrong_domain_type = "Domain of {0} {1} {2} not {3}" + wrong_range_type = "Range of {0} {1} {2} not {3}" + + count = 0 + schema = RDF.Node(RDF.Uri(SCHEMAS_URL)) + for s, context in self.model.as_stream_context(): + if context == schema: + continue + # check domain + query = RDF.SPARQLQuery(property_template.format( + predicate=s.predicate, + space='rdfs:domain')) + for r in query.execute(self.model): + if r['type'] == rdfsNS['Resource']: + continue + check = RDF.Statement(s.subject, rdfNS['type'], r['type']) + if not self.model.contains_statement(check): + yield wrong_domain_type.format(str(s.subject), + str(s.predicate), + str(s.object), + str(r['type'])) + # check range + query = RDF.SPARQLQuery(property_template.format( + predicate=s.predicate, + space='rdfs:range')) + for r in query.execute(self.model): + if r['type'] == rdfsNS['Resource']: + continue + check = RDF.Statement(s.object, rdfNS['type'], r['type']) + if not self.model.contains_statement(check): + yield wrong_range_type.format(str(s.subject), + str(s.predicate), + str(s.object), + str(r['type'])) + + return diff --git a/htsworkflow/util/rdfns.py b/htsworkflow/util/rdfns.py new file mode 100644 index 0000000..d2164ee --- /dev/null +++ b/htsworkflow/util/rdfns.py @@ -0,0 +1,25 @@ +"""Namespace definitions + +All in one place to make import rdfns.* work safely +""" +from RDF import NS + +# standard ontology namespaces +rdfNS = NS("http://www.w3.org/1999/02/22-rdf-syntax-ns#") +rdfsNS = NS("http://www.w3.org/2000/01/rdf-schema#") +owlNS = NS('http://www.w3.org/2002/07/owl#') +dcNS = NS("http://purl.org/dc/elements/1.1/") +xmlNS = NS('http://www.w3.org/XML/1998/namespace') +xsdNS = NS("http://www.w3.org/2001/XMLSchema#") +vsNS = NS('http://www.w3.org/2003/06/sw-vocab-status/ns#') +wotNS = NS('http://xmlns.com/wot/0.1/') + +# internal ontologies +submissionOntology = NS( + "http://jumpgate.caltech.edu/wiki/UcscSubmissionOntology#") +dafTermOntology = NS("http://jumpgate.caltech.edu/wiki/UcscDaf#") +libraryOntology = NS("http://jumpgate.caltech.edu/wiki/LibraryOntology#") +inventoryOntology = NS( + "http://jumpgate.caltech.edu/wiki/InventoryOntology#") +submissionLog = NS("http://jumpgate.caltech.edu/wiki/SubmissionsLog/") +geoSoftNS = NS('http://www.ncbi.nlm.nih.gov/geo/info/soft2.html#') diff --git a/htsworkflow/util/schemas/dc.turtle b/htsworkflow/util/schemas/dc.turtle new file mode 100644 index 0000000..2aa6337 --- /dev/null +++ b/htsworkflow/util/schemas/dc.turtle @@ -0,0 +1,28 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix dc: . +@prefix grddl: . +@prefix xml: . +@prefix xsd: . +@prefix vs: . +@prefix foaf: . +@prefix wot: . + +# this is just a subset of dublin core + + dc:title "DCMI Metadata Terms" ; + rdfs:comment "Metadata terms maintained by the Dublin Core Metadata Initiative" ; + a owl:Ontology ; + rdfs:seeAlso . + +dc:title + a rdf:Property ; + rdfs:comment "A name given to the resource"@en ; + rdfs:range rdfs:Literal . + +dc:description + a rdf:Property ; + rdfs:label "Description"@en ; + rdfs:comment "An account of the resource"@en ; + rdfs:range rdfs:Literal . diff --git a/htsworkflow/util/schemas/owl.turtle b/htsworkflow/util/schemas/owl.turtle new file mode 100644 index 0000000..fd2c392 --- /dev/null +++ b/htsworkflow/util/schemas/owl.turtle @@ -0,0 +1,556 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix dc: . +@prefix grddl: . +@prefix xml: . +@prefix xsd: . +@prefix vs: . +@prefix foaf: . +@prefix wot: . + + + a owl:Ontology ; + dc:title "The OWL 2 Schema vocabulary (OWL 2)" ; + rdfs:comment """ + This ontology partially describes the built-in classes and + properties that together form the basis of the RDF/XML syntax of OWL 2. + The content of this ontology is based on Tables 6.1 and 6.2 + in Section 6.4 of the OWL 2 RDF-Based Semantics specification, + available at http://www.w3.org/TR/owl2-rdf-based-semantics/. + Please note that those tables do not include the different annotations + (labels, comments and rdfs:isDefinedBy links) used in this file. + Also note that the descriptions provided in this ontology do not + provide a complete and correct formal description of either the syntax + or the semantics of the introduced terms (please see the OWL 2 + recommendations for the complete and normative specifications). + Furthermore, the information provided by this ontology may be + misleading if not used with care. This ontology SHOULD NOT be imported + into OWL ontologies. Importing this file into an OWL 2 DL ontology + will cause it to become an OWL 2 Full ontology and may have other, + unexpected, consequences. + """ ; + rdfs:isDefinedBy + , + , + ; + rdfs:seeAlso , + ; + owl:imports ; + owl:versionIRI ; + owl:versionInfo "$Date: 2009/11/15 10:54:12 $" ; + # grddl:namespaceTransformation + . + + +owl:AllDifferent a rdfs:Class ; + rdfs:label "AllDifferent" ; + rdfs:comment "The class of collections of pairwise different individuals." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:AllDisjointClasses a rdfs:Class ; + rdfs:label "AllDisjointClasses" ; + rdfs:comment "The class of collections of pairwise disjoint classes." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:AllDisjointProperties a rdfs:Class ; + rdfs:label "AllDisjointProperties" ; + rdfs:comment "The class of collections of pairwise disjoint properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:Annotation a rdfs:Class ; + rdfs:label "Annotation" ; + rdfs:comment "The class of annotated annotations for which the RDF serialization consists of an annotated subject, predicate and object." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:AnnotationProperty a rdfs:Class ; + rdfs:label "AnnotationProperty" ; + rdfs:comment "The class of annotation properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:AsymmetricProperty a rdfs:Class ; + rdfs:label "AsymmetricProperty" ; + rdfs:comment "The class of asymmetric properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:Axiom a rdfs:Class ; + rdfs:label "Axiom" ; + rdfs:comment "The class of annotated axioms for which the RDF serialization consists of an annotated subject, predicate and object." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:Class a rdfs:Class ; + rdfs:label "Class" ; + rdfs:comment "The class of OWL classes." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Class . + +owl:DataRange a rdfs:Class ; + rdfs:label "DataRange" ; + rdfs:comment "The class of OWL data ranges, which are special kinds of datatypes. Note: The use of the IRI owl:DataRange has been deprecated as of OWL 2. The IRI rdfs:Datatype SHOULD be used instead." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Datatype . + +owl:DatatypeProperty a rdfs:Class ; + rdfs:label "DatatypeProperty" ; + rdfs:comment "The class of data properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:DeprecatedClass a rdfs:Class ; + rdfs:label "DeprecatedClass" ; + rdfs:comment "The class of deprecated classes." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Class . + +owl:DeprecatedProperty a rdfs:Class ; + rdfs:label "DeprecatedProperty" ; + rdfs:comment "The class of deprecated properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:FunctionalProperty a rdfs:Class ; + rdfs:label "FunctionalProperty" ; + rdfs:comment "The class of functional properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:InverseFunctionalProperty a rdfs:Class ; + rdfs:label "InverseFunctionalProperty" ; + rdfs:comment "The class of inverse-functional properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:IrreflexiveProperty a rdfs:Class ; + rdfs:label "IrreflexiveProperty" ; + rdfs:comment "The class of irreflexive properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:NamedIndividual a rdfs:Class ; + rdfs:label "NamedIndividual" ; + rdfs:comment "The class of named individuals." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:Thing . + +owl:NegativePropertyAssertion a rdfs:Class ; + rdfs:label "NegativePropertyAssertion" ; + rdfs:comment "The class of negative property assertions." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:Nothing a owl:Class ; + rdfs:label "Nothing" ; + rdfs:comment "This is the empty class." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:Thing . + +owl:ObjectProperty a rdfs:Class ; + rdfs:label "ObjectProperty" ; + rdfs:comment "The class of object properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:Ontology a rdfs:Class ; + rdfs:label "Ontology" ; + rdfs:comment "The class of ontologies." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdfs:Resource . + +owl:OntologyProperty a rdfs:Class ; + rdfs:label "OntologyProperty" ; + rdfs:comment "The class of ontology properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf rdf:Property . + +owl:ReflexiveProperty a rdfs:Class ; + rdfs:label "ReflexiveProperty" ; + rdfs:comment "The class of reflexive properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:Restriction a rdfs:Class ; + rdfs:label "Restriction" ; + rdfs:comment "The class of property restrictions." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:Class . + +owl:SymmetricProperty a rdfs:Class ; + rdfs:label "SymmetricProperty" ; + rdfs:comment "The class of symmetric properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:TransitiveProperty a rdfs:Class ; + rdfs:label "TransitiveProperty" ; + rdfs:comment "The class of transitive properties." ; + rdfs:isDefinedBy ; + rdfs:subClassOf owl:ObjectProperty . + +owl:Thing a owl:Class , rdfs:Class ; + rdfs:label "Thing" ; + rdfs:comment "The class of OWL individuals." ; + rdfs:isDefinedBy . + +owl:allValuesFrom a rdf:Property ; + rdfs:label "allValuesFrom" ; + rdfs:comment "The property that determines the class that a universal property restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Class . + +owl:annotatedProperty a rdf:Property ; + rdfs:label "annotatedProperty" ; + rdfs:comment "The property that determines the predicate of an annotated axiom or annotated annotation." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:annotatedSource a rdf:Property ; + rdfs:label "annotatedSource" ; + rdfs:comment "The property that determines the subject of an annotated axiom or annotated annotation." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:annotatedTarget a rdf:Property ; + rdfs:label "annotatedTarget" ; + rdfs:comment "The property that determines the object of an annotated axiom or annotated annotation." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:assertionProperty a rdf:Property ; + rdfs:label "assertionProperty" ; + rdfs:comment "The property that determines the predicate of a negative property assertion." ; + rdfs:domain owl:NegativePropertyAssertion ; + rdfs:isDefinedBy ; + rdfs:range rdf:Property . + +owl:backwardCompatibleWith a owl:AnnotationProperty, owl:OntologyProperty ; + rdfs:label "backwardCompatibleWith" ; + rdfs:comment "The annotation property that indicates that a given ontology is backward compatible with another ontology." ; + rdfs:domain owl:Ontology ; + rdfs:isDefinedBy ; + rdfs:range owl:Ontology . + +owl:bottomDataProperty a owl:DatatypeProperty ; + rdfs:label "bottomDataProperty" ; + rdfs:comment "The data property that does not relate any individual to any data value." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Literal . + +owl:bottomObjectProperty a owl:ObjectProperty ; + rdfs:label "bottomObjectProperty" ; + rdfs:comment "The object property that does not relate any two individuals." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:cardinality a rdf:Property ; + rdfs:label "cardinality" ; + rdfs:comment "The property that determines the cardinality of an exact cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:complementOf a rdf:Property ; + rdfs:label "complementOf" ; + rdfs:comment "The property that determines that a given class is the complement of another class." ; + rdfs:domain owl:Class ; + rdfs:isDefinedBy ; + rdfs:range owl:Class . + +owl:datatypeComplementOf a rdf:Property ; + rdfs:label "datatypeComplementOf" ; + rdfs:comment "The property that determines that a given data range is the complement of another data range with respect to the data domain." ; + rdfs:domain rdfs:Datatype ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Datatype . + +owl:deprecated a owl:AnnotationProperty ; + rdfs:label "deprecated" ; + rdfs:comment "The annotation property that indicates that a given entity has been deprecated." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:differentFrom a rdf:Property ; + rdfs:label "differentFrom" ; + rdfs:comment "The property that determines that two given individuals are different." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:disjointUnionOf a rdf:Property ; + rdfs:label "disjointUnionOf" ; + rdfs:comment "The property that determines that a given class is equivalent to the disjoint union of a collection of other classes." ; + rdfs:domain owl:Class ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:disjointWith a rdf:Property ; + rdfs:label "disjointWith" ; + rdfs:comment "The property that determines that two given classes are disjoint." ; + rdfs:domain owl:Class ; + rdfs:isDefinedBy ; + rdfs:range owl:Class . + +owl:distinctMembers a rdf:Property ; + rdfs:label "distinctMembers" ; + rdfs:comment "The property that determines the collection of pairwise different individuals in a owl:AllDifferent axiom." ; + rdfs:domain owl:AllDifferent ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:equivalentClass a rdf:Property ; + rdfs:label "equivalentClass" ; + rdfs:comment "The property that determines that two given classes are equivalent, and that is used to specify datatype definitions." ; + rdfs:domain rdfs:Class ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Class . + +owl:equivalentProperty a rdf:Property ; + rdfs:label "equivalentProperty" ; + rdfs:comment "The property that determines that two given properties are equivalent." ; + rdfs:domain rdf:Property ; + rdfs:isDefinedBy ; + rdfs:range rdf:Property . + +owl:hasKey a rdf:Property ; + rdfs:label "hasKey" ; + rdfs:comment "The property that determines the collection of properties that jointly build a key." ; + rdfs:domain owl:Class ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:hasSelf a rdf:Property ; + rdfs:label "hasSelf" ; + rdfs:comment "The property that determines the property that a self restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:hasValue a rdf:Property ; + rdfs:label "hasValue" ; + rdfs:comment "The property that determines the individual that a has-value restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:imports a owl:OntologyProperty ; + rdfs:label "imports" ; + rdfs:comment "The property that is used for importing other ontologies into a given ontology." ; + rdfs:domain owl:Ontology ; + rdfs:isDefinedBy ; + rdfs:range owl:Ontology . + +owl:incompatibleWith a owl:AnnotationProperty, owl:OntologyProperty ; + rdfs:label "incompatibleWith" ; + rdfs:comment "The annotation property that indicates that a given ontology is incompatible with another ontology." ; + rdfs:domain owl:Ontology ; + rdfs:isDefinedBy ; + rdfs:range owl:Ontology . + +owl:intersectionOf a rdf:Property ; + rdfs:label "intersectionOf" ; + rdfs:comment "The property that determines the collection of classes or data ranges that build an intersection." ; + rdfs:domain rdfs:Class ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:inverseOf a rdf:Property ; + rdfs:label "inverseOf" ; + rdfs:comment "The property that determines that two given properties are inverse." ; + rdfs:domain owl:ObjectProperty ; + rdfs:isDefinedBy ; + rdfs:range owl:ObjectProperty . + +owl:maxCardinality a rdf:Property ; + rdfs:label "maxCardinality" ; + rdfs:comment "The property that determines the cardinality of a maximum cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:maxQualifiedCardinality a rdf:Property ; + rdfs:label "maxQualifiedCardinality" ; + rdfs:comment "The property that determines the cardinality of a maximum qualified cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:members a rdf:Property ; + rdfs:label "members" ; + rdfs:comment "The property that determines the collection of members in either a owl:AllDifferent, owl:AllDisjointClasses or owl:AllDisjointProperties axiom." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:minCardinality a rdf:Property ; + rdfs:label "minCardinality" ; + rdfs:comment "The property that determines the cardinality of a minimum cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:minQualifiedCardinality a rdf:Property ; + rdfs:label "minQualifiedCardinality" ; + rdfs:comment "The property that determines the cardinality of a minimum qualified cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:onClass a rdf:Property ; + rdfs:label "onClass" ; + rdfs:comment "The property that determines the class that a qualified object cardinality restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range owl:Class . + +owl:onDataRange a rdf:Property ; + rdfs:label "onDataRange" ; + rdfs:comment "The property that determines the data range that a qualified data cardinality restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Datatype . + +owl:onDatatype a rdf:Property ; + rdfs:label "onDatatype" ; + rdfs:comment "The property that determines the datatype that a datatype restriction refers to." ; + rdfs:domain rdfs:Datatype ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Datatype . + +owl:oneOf a rdf:Property ; + rdfs:label "oneOf" ; + rdfs:comment "The property that determines the collection of individuals or data values that build an enumeration." ; + rdfs:domain rdfs:Class ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:onProperties a rdf:Property ; + rdfs:label "onProperties" ; + rdfs:comment "The property that determines the n-tuple of properties that a property restriction on an n-ary data range refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:onProperty a rdf:Property ; + rdfs:label "onProperty" ; + rdfs:comment "The property that determines the property that a property restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdf:Property . + +owl:priorVersion a owl:AnnotationProperty, owl:OntologyProperty ; + rdfs:label "priorVersion" ; + rdfs:comment "The annotation property that indicates the predecessor ontology of a given ontology." ; + rdfs:domain owl:Ontology ; + rdfs:isDefinedBy ; + rdfs:range owl:Ontology . + +owl:propertyChainAxiom a rdf:Property ; + rdfs:label "propertyChainAxiom" ; + rdfs:comment "The property that determines the n-tuple of properties that build a sub property chain of a given property." ; + rdfs:domain owl:ObjectProperty ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:propertyDisjointWith a rdf:Property ; + rdfs:label "propertyDisjointWith" ; + rdfs:comment "The property that determines that two given properties are disjoint." ; + rdfs:domain rdf:Property ; + rdfs:isDefinedBy ; + rdfs:range rdf:Property . + +owl:qualifiedCardinality a rdf:Property ; + rdfs:label "qualifiedCardinality" ; + rdfs:comment "The property that determines the cardinality of an exact qualified cardinality restriction." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range xsd:nonNegativeInteger . + +owl:sameAs a rdf:Property ; + rdfs:label "sameAs" ; + rdfs:comment "The property that determines that two given individuals are equal." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:someValuesFrom a rdf:Property ; + rdfs:label "someValuesFrom" ; + rdfs:comment "The property that determines the class that an existential property restriction refers to." ; + rdfs:domain owl:Restriction ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Class . + +owl:sourceIndividual a rdf:Property ; + rdfs:label "sourceIndividual" ; + rdfs:comment "The property that determines the subject of a negative property assertion." ; + rdfs:domain owl:NegativePropertyAssertion ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:targetIndividual a rdf:Property ; + rdfs:label "targetIndividual" ; + rdfs:comment "The property that determines the object of a negative object property assertion." ; + rdfs:domain owl:NegativePropertyAssertion ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:targetValue a rdf:Property ; + rdfs:label "targetValue" ; + rdfs:comment "The property that determines the value of a negative data property assertion." ; + rdfs:domain owl:NegativePropertyAssertion ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Literal . + +owl:topDataProperty a owl:DatatypeProperty ; + rdfs:label "topDataProperty" ; + rdfs:comment "The data property that relates every individual to every data value." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Literal . + +owl:topObjectProperty a owl:ObjectProperty ; + rdfs:label "topObjectProperty" ; + rdfs:comment "The object property that relates every two individuals." ; + rdfs:domain owl:Thing ; + rdfs:isDefinedBy ; + rdfs:range owl:Thing . + +owl:unionOf a rdf:Property ; + rdfs:label "unionOf" ; + rdfs:comment "The property that determines the collection of classes or data ranges that build a union." ; + rdfs:domain rdfs:Class ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . + +owl:versionInfo a owl:AnnotationProperty ; + rdfs:label "versionInfo" ; + rdfs:comment "The annotation property that provides version information for an ontology or another OWL construct." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:range rdfs:Resource . + +owl:versionIRI a owl:OntologyProperty ; + rdfs:label "versionIRI" ; + rdfs:comment "The property that identifies the version IRI of an ontology." ; + rdfs:domain owl:Ontology ; + rdfs:isDefinedBy ; + rdfs:range owl:Ontology . + +owl:withRestrictions a rdf:Property ; + rdfs:label "withRestrictions" ; + rdfs:comment "The property that determines the collection of facet-value pairs that define a datatype restriction." ; + rdfs:domain rdfs:Datatype ; + rdfs:isDefinedBy ; + rdfs:range rdf:List . diff --git a/htsworkflow/util/schemas/rdf.turtle b/htsworkflow/util/schemas/rdf.turtle new file mode 100644 index 0000000..ce337be --- /dev/null +++ b/htsworkflow/util/schemas/rdf.turtle @@ -0,0 +1,258 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix dc: . +@prefix grddl: . +@prefix xml: . +@prefix xsd: . +@prefix vs: . +@prefix foaf: . +@prefix wot: . + + + dc:description "This is the RDF Schema for the RDF vocabulary defined in the RDF namespace."@en ; + dc:title "The RDF Vocabulary (RDF)"@en ; + a owl:Ontology ; + rdfs:seeAlso . + +rdf:Alt + a rdfs:Class ; + rdfs:comment "The class of containers of alternatives." ; + rdfs:isDefinedBy ; + rdfs:label "Alt" ; + rdfs:subClassOf rdfs:Container . + +rdf:Bag + a rdfs:Class ; + rdfs:comment "The class of unordered containers." ; + rdfs:isDefinedBy ; + rdfs:label "Bag" ; + rdfs:subClassOf rdfs:Container . + +rdf:List + a rdfs:Class ; + rdfs:comment "The class of RDF Lists." ; + rdfs:isDefinedBy ; + rdfs:label "List" ; + rdfs:subClassOf rdfs:Resource . + +rdf:PlainLiteral + a rdfs:Datatype ; + rdfs:comment "The class of plain (i.e. untyped) literal values." ; + rdfs:isDefinedBy ; + rdfs:label "PlainLiteral" ; + rdfs:subClassOf rdfs:Literal . + +rdf:Property + a rdfs:Class ; + rdfs:comment "The class of RDF properties." ; + rdfs:isDefinedBy ; + rdfs:label "Property" ; + rdfs:subClassOf rdfs:Resource . + +rdf:Seq + a rdfs:Class ; + rdfs:comment "The class of ordered containers." ; + rdfs:isDefinedBy ; + rdfs:label "Seq" ; + rdfs:subClassOf rdfs:Container . + +rdf:Statement + a rdfs:Class ; + rdfs:comment "The class of RDF statements." ; + rdfs:isDefinedBy ; + rdfs:label "Statement" ; + rdfs:subClassOf rdfs:Resource . + +rdf:XMLLiteral + a rdfs:Datatype ; + rdfs:comment "The class of XML literal values." ; + rdfs:isDefinedBy ; + rdfs:label "XMLLiteral" ; + rdfs:subClassOf rdfs:Literal . + +rdf:first + a rdf:Property ; + rdfs:comment "The first item in the subject RDF list." ; + rdfs:domain rdf:List ; + rdfs:isDefinedBy ; + rdfs:label "first" ; + rdfs:range rdfs:Resource . + +rdf:nil + a rdf:List ; + rdfs:comment "The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it." ; + rdfs:isDefinedBy ; + rdfs:label "nil" . + +rdf:object + a rdf:Property ; + rdfs:comment "The object of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "object" ; + rdfs:range rdfs:Resource . + +rdf:predicate + a rdf:Property ; + rdfs:comment "The predicate of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "predicate" ; + rdfs:range rdfs:Resource . + +rdf:rest + a rdf:Property ; + rdfs:comment "The rest of the subject RDF list after the first item." ; + rdfs:domain rdf:List ; + rdfs:isDefinedBy ; + rdfs:label "rest" ; + rdfs:range rdf:List . + +rdf:subject + a rdf:Property ; + rdfs:comment "The subject of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "subject" ; + rdfs:range rdfs:Resource . + +rdf:type + a rdf:Property ; + rdfs:comment "The subject is an instance of a class." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "type" ; + rdfs:range rdfs:Class . + +rdf:value + a rdf:Property ; + rdfs:comment "Idiomatic property used for structured values." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "value" ; + rdfs:range rdfs:Resource . + + + dc:description "This is the RDF Schema for the RDF vocabulary defined in the RDF namespace."@en ; + dc:title "The RDF Vocabulary (RDF)"@en ; + a owl:Ontology ; + rdfs:seeAlso . + +rdf:Alt + a rdfs:Class ; + rdfs:comment "The class of containers of alternatives." ; + rdfs:isDefinedBy ; + rdfs:label "Alt" ; + rdfs:subClassOf rdfs:Container . + +rdf:Bag + a rdfs:Class ; + rdfs:comment "The class of unordered containers." ; + rdfs:isDefinedBy ; + rdfs:label "Bag" ; + rdfs:subClassOf rdfs:Container . + +rdf:List + a rdfs:Class ; + rdfs:comment "The class of RDF Lists." ; + rdfs:isDefinedBy ; + rdfs:label "List" ; + rdfs:subClassOf rdfs:Resource . + +rdf:PlainLiteral + a rdfs:Datatype ; + rdfs:comment "The class of plain (i.e. untyped) literal values." ; + rdfs:isDefinedBy ; + rdfs:label "PlainLiteral" ; + rdfs:subClassOf rdfs:Literal . + +rdf:Property + a rdfs:Class ; + rdfs:comment "The class of RDF properties." ; + rdfs:isDefinedBy ; + rdfs:label "Property" ; + rdfs:subClassOf rdfs:Resource . + +rdf:Seq + a rdfs:Class ; + rdfs:comment "The class of ordered containers." ; + rdfs:isDefinedBy ; + rdfs:label "Seq" ; + rdfs:subClassOf rdfs:Container . + +rdf:Statement + a rdfs:Class ; + rdfs:comment "The class of RDF statements." ; + rdfs:isDefinedBy ; + rdfs:label "Statement" ; + rdfs:subClassOf rdfs:Resource . + +rdf:XMLLiteral + a rdfs:Datatype ; + rdfs:comment "The class of XML literal values." ; + rdfs:isDefinedBy ; + rdfs:label "XMLLiteral" ; + rdfs:subClassOf rdfs:Literal . + +rdf:first + a rdf:Property ; + rdfs:comment "The first item in the subject RDF list." ; + rdfs:domain rdf:List ; + rdfs:isDefinedBy ; + rdfs:label "first" ; + rdfs:range rdfs:Resource . + +rdf:nil + a rdf:List ; + rdfs:comment "The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it." ; + rdfs:isDefinedBy ; + rdfs:label "nil" . + +rdf:object + a rdf:Property ; + rdfs:comment "The object of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "object" ; + rdfs:range rdfs:Resource . + +rdf:predicate + a rdf:Property ; + rdfs:comment "The predicate of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "predicate" ; + rdfs:range rdfs:Resource . + +rdf:rest + a rdf:Property ; + rdfs:comment "The rest of the subject RDF list after the first item." ; + rdfs:domain rdf:List ; + rdfs:isDefinedBy ; + rdfs:label "rest" ; + rdfs:range rdf:List . + +rdf:subject + a rdf:Property ; + rdfs:comment "The subject of the subject RDF statement." ; + rdfs:domain rdf:Statement ; + rdfs:isDefinedBy ; + rdfs:label "subject" ; + rdfs:range rdfs:Resource . + +rdf:type + a rdf:Property ; + rdfs:comment "The subject is an instance of a class." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "type" ; + rdfs:range rdfs:Class . + +rdf:value + a rdf:Property ; + rdfs:comment "Idiomatic property used for structured values." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "value" ; + rdfs:range rdfs:Resource . diff --git a/htsworkflow/util/schemas/rdfs.turtle b/htsworkflow/util/schemas/rdfs.turtle new file mode 100644 index 0000000..dc642f4 --- /dev/null +++ b/htsworkflow/util/schemas/rdfs.turtle @@ -0,0 +1,130 @@ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix dc: . +@prefix grddl: . +@prefix xml: . +@prefix xsd: . +@prefix vs: . +@prefix foaf: . +@prefix wot: . + + + dc:title "The RDF Schema vocabulary (RDFS)" ; + a owl:Ontology ; + rdfs:seeAlso . + +rdfs:Class + a rdfs:Class ; + rdfs:comment "The class of classes." ; + rdfs:isDefinedBy ; + rdfs:label "Class" ; + rdfs:subClassOf rdfs:Resource . + +rdfs:Container + a rdfs:Class ; + rdfs:comment "The class of RDF containers." ; + rdfs:isDefinedBy ; + rdfs:label "Container" ; + rdfs:subClassOf rdfs:Resource . + +rdfs:ContainerMembershipProperty + a rdfs:Class ; + rdfs:comment """The class of container membership properties, rdf:_1, rdf:_2, ..., + all of which are sub-properties of 'member'.""" ; + rdfs:isDefinedBy ; + rdfs:label "ContainerMembershipProperty" ; + rdfs:subClassOf rdf:Property . + +rdfs:Datatype + a rdfs:Class ; + rdfs:comment "The class of RDF datatypes." ; + rdfs:isDefinedBy ; + rdfs:label "Datatype" ; + rdfs:subClassOf rdfs:Class . + +rdfs:Literal + a rdfs:Class ; + rdfs:comment "The class of literal values, eg. textual strings and integers." ; + rdfs:isDefinedBy ; + rdfs:label "Literal" ; + rdfs:subClassOf rdfs:Resource . + +rdfs:Resource + a rdfs:Class ; + rdfs:comment "The class resource, everything." ; + rdfs:isDefinedBy ; + rdfs:label "Resource" . + +rdfs:comment + a rdf:Property ; + rdfs:comment "A description of the subject resource." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "comment" ; + rdfs:range rdfs:Literal . + +rdfs:domain + a rdf:Property ; + rdfs:comment "A domain of the subject property." ; + rdfs:domain rdf:Property ; + rdfs:isDefinedBy ; + rdfs:label "domain" ; + rdfs:range rdfs:Class . + +rdfs:isDefinedBy + a rdf:Property ; + rdfs:comment "The defininition of the subject resource." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "isDefinedBy" ; + rdfs:range rdfs:Resource ; + rdfs:subPropertyOf rdfs:seeAlso . + +rdfs:label + a rdf:Property ; + rdfs:comment "A human-readable name for the subject." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "label" ; + rdfs:range rdfs:Literal . + +rdfs:member + a rdf:Property ; + rdfs:comment "A member of the subject resource." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "member" ; + rdfs:range rdfs:Resource . + +rdfs:range + a rdf:Property ; + rdfs:comment "A range of the subject property." ; + rdfs:domain rdf:Property ; + rdfs:isDefinedBy ; + rdfs:label "range" ; + rdfs:range rdfs:Class . + +rdfs:seeAlso + a rdf:Property ; + rdfs:comment "Further information about the subject resource." ; + rdfs:domain rdfs:Resource ; + rdfs:isDefinedBy ; + rdfs:label "seeAlso" ; + rdfs:range rdfs:Resource . + +rdfs:subClassOf + a rdf:Property ; + rdfs:comment "The subject is a subclass of a class." ; + rdfs:domain rdfs:Class ; + rdfs:isDefinedBy ; + rdfs:label "subClassOf" ; + rdfs:range rdfs:Class . + +rdfs:subPropertyOf + a rdf:Property ; + rdfs:comment "The subject is a subproperty of a property." ; + rdfs:domain rdf:Property ; + rdfs:isDefinedBy ; + rdfs:label "subPropertyOf" ; + rdfs:range rdf:Property . diff --git a/htsworkflow/util/test/test_rdfhelp.py b/htsworkflow/util/test/test_rdfhelp.py index d331416..9a31ca9 100644 --- a/htsworkflow/util/test/test_rdfhelp.py +++ b/htsworkflow/util/test/test_rdfhelp.py @@ -6,14 +6,19 @@ import types from datetime import datetime from htsworkflow.util.rdfhelp import \ + add_default_schemas, \ blankOrUri, \ + dcNS, \ dump_model, \ fromTypedNode, \ get_model, \ guess_parser, \ guess_parser_by_extension, \ load_string_into_model, \ + owlNS, \ + rdfNS, \ rdfsNS, \ + remove_schemas, \ toTypedNode, \ stripNamespace, \ simplify_uri, \ @@ -215,6 +220,38 @@ _:a owl:imports "{loc}extra.turtle" . for contenttype, url, parser in DATA: self.assertEqual(guess_parser(contenttype, url), parser) + class TestRDFSchemas(unittest.TestCase): + def test_rdf_schema(self): + """Does it basically work? + """ + model = get_model() + self.assertEqual(model.size(), 0) + add_default_schemas(model) + self.assertGreater(model.size(), 0) + remove_schemas(model) + self.assertEqual(model.size(), 0) + + def test_included_schemas(self): + model = get_model() + add_default_schemas(model) + + # rdf test + s = RDF.Statement(rdfNS[''], dcNS['title'], None) + title = model.get_target(rdfNS[''], dcNS['title']) + self.assertTrue(title is not None) + + s = RDF.Statement(rdfNS['Property'], rdfNS['type'], rdfsNS['Class']) + self.assertTrue(model.contains_statement(s)) + + # rdfs test + s = RDF.Statement(rdfsNS['Class'], rdfNS['type'], rdfsNS['Class']) + self.assertTrue(model.contains_statement(s)) + + s = RDF.Statement(owlNS['inverseOf'], rdfNS['type'], + rdfNS['Property']) + self.assertTrue(model.contains_statement(s)) + + def suite(): return unittest.makeSuite(TestRDFHelp, 'test') except ImportError, e: diff --git a/htsworkflow/util/test/test_rdfinfer.py b/htsworkflow/util/test/test_rdfinfer.py new file mode 100644 index 0000000..48462e4 --- /dev/null +++ b/htsworkflow/util/test/test_rdfinfer.py @@ -0,0 +1,183 @@ +import unittest + +import RDF + +from htsworkflow.util.rdfhelp import get_model, \ + add_default_schemas, add_schema, load_string_into_model, dump_model +from htsworkflow.util.rdfns import * +from htsworkflow.util.rdfinfer import Infer + +foafNS = RDF.NS('http://xmlns.com/foaf/0.1/') + +MINI_FOAF_ONTOLOGY = """ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix foaf: . + + +foaf:Agent + a rdfs:Class, owl:Class ; + rdfs:comment "An agent (person, group, software or physical artifiact)."@en; + rdfs:label "Agent" . + +foaf:Person + a rdfs:Class, owl:Class, foaf:Agent ; + rdfs:label "Person" . + +foaf:age + a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ; + rdfs:comment "The age in years of some agent." ; + rdfs:domain foaf:Agent ; + rdfs:label "age"; + rdfs:range rdfs:Literal . + +foaf:familyName + a rdf:Property, owl:DatatypeProperty ; + rdfs:comment "Family name of some person." ; + rdfs:label "familyName" ; + rdfs:domain foaf:Person ; + rdfs:range rdfs:Literal . + +foaf:firstName + a rdf:Property, owl:DatatypeProperty ; + rdfs:comment "the first name of a person." ; + rdfs:domain foaf:Person ; + rdfs:label "firstname" ; + rdfs:range rdfs:Literal . + +foaf:Document + a rdfs:Class, owl:Class ; + rdfs:comment "A document." . + +foaf:Image + a rdfs:Class, owl:Class ; + rdfs:comment "An image." ; + rdfs:subClassOf foaf:Document . + +foaf:depicts + a rdf:Property, owl:ObjectProperty ; + rdfs:comment "A thing depicted in this representation." ; + rdfs:domain foaf:Image ; + rdfs:range owl:Thing ; + owl:inverseOf foaf:depiction . + +foaf:depiction + a rdf:Property, owl:ObjectProperty ; + rdfs:comment "Depiction of some thing." ; + rdfs:domain owl:Thing ; + rdfs:range foaf:Image ; + owl:inverseOf foaf:depicts . +""" + +FOAF_DATA = """ +@prefix rdf: . +@prefix rdfs: . +@prefix owl: . +@prefix foaf: . + +_:me + foaf:firstName "Diane" ; + foaf:familyName "Trout" ; + a foaf:Person, owl:Thing ; + "value" ; + . + + + a foaf:Image, owl:Thing ; + foaf:depicts _:me . +""" + +class TestInfer(unittest.TestCase): + def setUp(self): + self.model = get_model() + add_default_schemas(self.model) + load_string_into_model(self.model, 'turtle', MINI_FOAF_ONTOLOGY) + + def test_inverse_of(self): + fooNS = RDF.NS('http://example.org/') + load_string_into_model(self.model, 'turtle', FOAF_DATA) + inference = Infer(self.model) + depiction = RDF.Statement(None, + foafNS['depiction'], + fooNS['me.jpg']) + size = self.model.size() + found_statements = list(self.model.find_statements(depiction)) + self.assertEqual(len(found_statements), 0) + inference._rule_inverse_of() + found_statements = list(self.model.find_statements(depiction)) + self.assertEqual(len(found_statements), 1) + + # we should've added one statement. + self.assertEqual(self.model.size(), size + 1) + + size = self.model.size() + inference._rule_inverse_of() + # we should already have both versions in our model + self.assertEqual(self.model.size(), size) + + def test_validate_types(self): + fooNS = RDF.NS('http://example.org/') + load_string_into_model(self.model, 'turtle', FOAF_DATA) + inference = Infer(self.model) + + errors = list(inference._validate_types()) + self.assertEqual(len(errors), 0) + + s = RDF.Statement(fooNS['document'], + dcNS['title'], + RDF.Node("bleem")) + self.model.append(s) + errors = list(inference._validate_types()) + self.assertEqual(len(errors), 1) + + def test_validate_undefined_properties(self): + fooNS = RDF.NS('http://example.org/') + inference = Infer(self.model) + + errors = list(inference._validate_undefined_properties()) + self.assertEqual(len(errors), 0) + + load_string_into_model(self.model, 'turtle', FOAF_DATA) + + errors = list(inference._validate_undefined_properties()) + self.assertEqual(len(errors), 2) + + + def test_validate_undefined_properties(self): + fooNS = RDF.NS('http://example.org/') + foafNS = RDF.NS('http://xmlns.com/foaf/0.1/') + load_string_into_model(self.model, 'turtle', FOAF_DATA) + inference = Infer(self.model) + + errors = list(inference._validate_property_types()) + self.assertEqual(len(errors), 0) + + s = RDF.Statement(fooNS['me.jpg'], + foafNS['firstName'], + RDF.Node("name")) + self.model.append(s) + errors = list(inference._validate_property_types()) + self.assertEqual(len(errors), 1) + self.assertTrue(errors[0].startswith('Domain of http://example.org')) + del self.model[s] + + errors = list(inference._validate_property_types()) + self.assertEqual(len(errors), 0) + s = RDF.Statement(fooNS['foo.txt'], rdfNS['type'], foafNS['Document']) + self.model.append(s) + s = RDF.Statement(fooNS['me.jpg'], + foafNS['depicts'], + foafNS['foo.txt']) + self.model.append(s) + + errors = list(inference._validate_property_types()) + self.assertEqual(len(errors), 1) + self.assertTrue(errors[0].startswith('Range of http://example.org')) + del self.model[s] + +def suite(): + return unittest.makeSuite(TestInfer, 'test') + +if __name__ == "__main__": + unittest.main(defaultTest='suite') diff --git a/setup.py b/setup.py index 0c1a203..5bbd5e9 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -from setuptools import setup +from setuptools import setup, find_packages from version import get_git_version setup( @@ -7,19 +7,7 @@ setup( description="Utilities to help manage high-through-put sequencing", author="Diane Trout, Brandon King", author_email="diane@caltech.edu", - packages=["htsworkflow", - "htsworkflow.automation", - "htsworkflow.pipelines", - "htsworkflow.util", - # django site - "htsworkflow.frontend", - "htsworkflow.frontend.analysis", - "htsworkflow.frontend.eland_config", - "htsworkflow.frontend.experiments", - "htsworkflow.frontend.inventory", - "htsworkflow.frontend.reports", - "htsworkflow.frontend.samples", - ], + packages=find_packages(), scripts=[ "scripts/htsw-copier", "scripts/htsw-eland2bed", @@ -36,4 +24,7 @@ setup( "scripts/htsw-update-archive", "scripts/htsw-validate", ], + package_data = { + '': ['*.turtle'] + }, ) -- 2.30.2