# rdf-reasoner Reasons over RDFS/OWL vocabularies and schema.org to generate statements which are entailed based on base RDFS/OWL rules along with vocabulary information. It can also be used to ask specific questions, such as if a given object is consistent with the vocabulary ruleset. This can be used to implement [SPARQL Entailment][] Regimes and [RDF Schema][] entailment. ## Features * Entail `rdfs:subClassOf` generating an array of terms which are ancestors of the subject. * Entail `rdfs:subPropertyOf` generating an array of terms which are ancestors of the subject. * Entail `rdfs:domain` and `rdfs:range` adding `rdf:type` assertions on the subject or object. * Inverse `rdfs:subClassOf` entailment, to find descendant classes of the subject term. * Entail `owl:equivalentClass` generating an array of terms equivalent to the subject. * Entail `owl:equivalentProperty` generating an array of terms equivalent to the subject. * `domainCompatible?` determines if a particular resource is compatible with the domain definition of a given predicate, based on the intersection of entailed subclasses with the property domain. * `rangeCompatible?` determines if a particular resource is compatible with the range definition of a given predicate, based on the intersection of entailed subclasses or literal types with the property domain. Domain and Range entailment include specific rules for schema.org vocabularies. * A plain literal is an acceptable value for any property. * If `resource` is of type `schema:Role`, `resource` is domain acceptable if any other resource references `resource` using the same property. * If `resource` is of type `schema:Role`, it is range acceptable if it has the same property with an acceptable value. * If `resource` is of type `rdf:List` (must be previously entailed), it is range acceptable if all members of the list are otherwise range acceptable on the same property. ## Examples ### Determine super-classes of a class require 'rdf/reasoner' RDF::Reasoner.apply(:rdfs) term = RDF::Vocabulary.find_term("http://xmlns.com/foaf/0.1/Person") term.entail(:subClassOf) # => [ foaf:Agent, http://www.w3.org/2000/10/swap/pim/contact#Person, geo:SpatialThing, foaf:Person ] ### Determine sub-classes of a class require 'rdf/reasoner' RDF::Reasoner.apply(:rdfs) term = RDF::FOAF.Person term.entail(:subClass) # => [foaf:Person, mo:SoloMusicArtist] ### Determine if a resource is compatible with the domains of a property require 'rdf/reasoner' require 'rdf/turtle' RDF::Reasoner.apply(:rdfs) graph = RDF::Graph.load("etc/doap.ttl") subj = RDF::URI("http://rubygems.org/gems/rdf-reasoner") RDF::DOAP.name.domain_compatible?(subj, graph) # => true ### Determine if a resource is compatible with the ranges of a property require 'rdf/reasoner' require 'rdf/turtle' RDF::Reasoner.apply(:rdfs) graph = RDF::Graph.load("etc/doap.ttl") obj = RDF::Literal(Date.new) RDF::DOAP.created.range_compatible?(obj, graph) # => true ### Perform equivalentClass entailment on a graph require 'rdf/reasoner' require 'rdf/turtle' RDF::Reasoner.apply(::owl) graph = RDF::Graph.load("etc/doap.ttl") graph.entail!(:equivalentClass) ### Yield all entailed statements for all entailment methods require 'rdf/reasoner' require 'rdf/turtle' RDF::Reasoner.apply(:rdfs, :owl) graph = RDF::Graph.load("etc/doap.ttl") graph.enum_statement.entail.count # >= graph.enum_statement.count ## Dependencies * [Ruby](http://ruby-lang.org/) (>= 1.9.2) * [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.1) ## Mailing List * ## Authors * [Gregg Kellogg](http://github.com/gkellogg) - ## Contributing * Do your best to adhere to the existing coding conventions and idioms. * Don't use hard tabs, and don't leave trailing whitespace on any line. Before committing, run `git diff --check` to make sure of this. * Do document every method you add using [YARD][] annotations. Read the [tutorial][YARD-GS] or just look at the existing code for examples. * Don't touch the `.gemspec`, `VERSION` or `AUTHORS` files. If you need to change them, do so on your private branch only. * Do feel free to add yourself to the `CREDITS` file and the corresponding list in the the `README`. Alphabetical order applies. * Do note that in order for us to merge any non-trivial changes (as a rule of thumb, additions larger than about 15 lines of code), we need an explicit [public domain dedication][PDD] on record from you. ## License This is free and unencumbered public domain software. For more information, see or the accompanying {file:UNLICENSE} file. [Ruby]: http://ruby-lang.org/ [RDF]: http://www.w3.org/RDF/ [YARD]: http://yardoc.org/ [YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md [PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html [SPARQL]: http://en.wikipedia.org/wiki/SPARQL [SPARQL Query]: http://www.w3.org/TR/2013/REC-sparql11-query-20130321/ [SPARQL Entailment]:http://www.w3.org/TR/sparql11-entailment/ [RDF 1.1]: http://www.w3.org/TR/rdf11-concepts [RDF.rb]: http://rdf.rubyforge.org/ [RDF Schema]: http://www.w3.org/TR/rdf-schema/ [Rack]: http://rack.rubyforge.org/