Module: RDF::Queryable
- Defined in:
- lib/rdf/reasoner/extensions.rb
Instance Method Summary collapse
-
#lint ⇒ Hash{Symbol => Hash{Symbol => Array<String>}}
Lint a queryable, presuming that it has already had RDFS entailment expansion.
Instance Method Details
#lint ⇒ Hash{Symbol => Hash{Symbol => Array<String>}}
Lint a queryable, presuming that it has already had RDFS entailment expansion.
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 |
# File 'lib/rdf/reasoner/extensions.rb', line 232 def lint = {} # Check for defined classes in known vocabularies self.query({predicate: RDF.type}) do |stmt| vocab = RDF::Vocabulary.find(stmt.object) term = (RDF::Vocabulary.find_term(stmt.object) rescue nil) if vocab pname = term ? term.pname : stmt.object.pname # Must be a defined term, not in RDF or RDFS vocabularies if term && term.class? # Warn against using a deprecated term superseded = term.properties[:'http://schema.org/supersededBy'] superseded = superseded.pname if superseded.respond_to?(:pname) ([:class] ||= {})[pname] = ["Term is superseded by #{superseded}"] if superseded else ([:class] ||= {})[pname] = ["No class definition found"] unless vocab.nil? || [RDF::RDFV, RDF::RDFS].include?(vocab) end end # Check for defined predicates in known vocabularies and domain/range resource_types = {} self.each_statement do |stmt| vocab = RDF::Vocabulary.find(stmt.predicate) term = (RDF::Vocabulary.find_term(stmt.predicate) rescue nil) if vocab pname = term ? term.pname : stmt.predicate.pname # Must be a valid statement begin stmt.validate! rescue (([:statement] ||= {})[pname] ||= []) << "Triple #{stmt.to_ntriples} is invalid" end # Must be a defined property if term.respond_to?(:property?) && term.property? # Warn against using a deprecated term superseded = term.properties[:'http://schema.org/supersededBy'] superseded = superseded.pname if superseded.respond_to?(:pname) ([:property] ||= {})[pname] = ["Term is superseded by #{superseded}"] if superseded else (([:property] ||= {})[pname] ||= []) << "No property definition found" unless vocab.nil? next end # See if type of the subject is in the domain of this predicate resource_types[stmt.subject] ||= self.query({subject: stmt.subject, predicate: RDF.type}). map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}. flatten. uniq. compact unless term.domain_compatible?(stmt.subject, self, types: resource_types[stmt.subject]) (([:property] ||= {})[pname] ||= []) << if !term.domain.empty? "Subject #{show_resource(stmt.subject)} not compatible with domain (#{Array(term.domain).map {|d| d.pname|| d}.join(',')})" else "Subject #{show_resource(stmt.subject)} not compatible with domainIncludes (#{term.domainIncludes.map {|d| d.pname|| d}.join(',')})" end end # Make sure that if ranges are defined, the object has an appropriate type resource_types[stmt.object] ||= self.query({subject: stmt.object, predicate: RDF.type}). map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}. flatten. uniq. compact if stmt.object.resource? unless term.range_compatible?(stmt.object, self, types: resource_types[stmt.object]) (([:property] ||= {})[pname] ||= []) << if !term.range.empty? "Object #{show_resource(stmt.object)} not compatible with range (#{Array(term.range).map {|d| d.pname|| d}.join(',')})" else "Object #{show_resource(stmt.object)} not compatible with rangeIncludes (#{term.rangeIncludes.map {|d| d.pname|| d}.join(',')})" end end end [:class].each {|k, v| [:class][k] = v.uniq} if [:class] [:property].each {|k, v| [:property][k] = v.uniq} if [:property] end |