rdf-reasoner 0.5.3 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 651a1431487e77d50420f0c33506df9d756e7eab48790589bdfacdc404b88fea
4
- data.tar.gz: 66c536de0f20de0fe2f50be36e8a712d24efd4e1ea7674b4bff234d91a827272
3
+ metadata.gz: 9089d2c2502a1b5bbb19919650e0cf29d447487c219c4f5ebd362b9146204e09
4
+ data.tar.gz: 9f0ffb2e5ec7b15bbd1a6773bcd7abf0dc3f2f2f55f61b9128affd5ed3ab9fa7
5
5
  SHA512:
6
- metadata.gz: 551d92044542d411803d75619a6f0d38d5cae5ae4331f7b11109006518a5db6c1fe8f7589d343e915b2e8187997a20fb68917771ebf5eba9297d0cc721e76be3
7
- data.tar.gz: 47ee7417fdf42130820419558718332ad77748386cec3d8ef4513e5e711b299fd4bdabe5500a12eb1effdc55acb19ba5a9bce41e3e4ef63ec2510ace662c9a0b
6
+ metadata.gz: 9d7ca4b250631e17f869e0c4161765c0af68cace0df7631a292cb9a3da7613140e6176b03d0c6a7692ad0a397e4448779d3f1dba6449d94f9f1ecfdb0a96dac2
7
+ data.tar.gz: 3b0320de434a264a235423b4e5c5b06b2430861f26931f7c1cdee4dcb78ad9396ecede761fd316219a71e99039f54fd3ac194e3cfe4744be50290064bcaa4308
data/README.md CHANGED
@@ -1,4 +1,13 @@
1
- # rdf-reasoner
1
+ # RDF::Reasoner
2
+
3
+ A partial RDFS/OWL/schema.org reasoner for [RDF.rb][].
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/rdf-reasoner.png)](https://badge.fury.io/rb/rdf-reasoner)
6
+ [![Build Status](https://github.com/ruby-rdf/rdf-reasoner/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/rdf-reasoner/actions?query=workflow%3ACI)
7
+ [![Coverage Status](https://coveralls.io/repos/ruby-rdf/rdf-reasoner/badge.svg?branch=develop)](https://coveralls.io/github/ruby-rdf/rdf-reasoner?branch=develop)
8
+ [![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
9
+
10
+ ## Description
2
11
 
3
12
  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.
4
13
 
@@ -22,6 +31,14 @@ Domain and Range entailment include specific rules for schema.org vocabularies.
22
31
  * If `resource` is of type `schema:Role`, it is range acceptable if it has the same property with an acceptable value.
23
32
  * 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.
24
33
 
34
+ ### Limiting vocabularies used for reasoning
35
+
36
+ As loading vocabularies can dominate processing time, the `RDF::Vocabulary.limit_vocabs` method can be used to set a specific set of vocabularies over which to reason. For example:
37
+
38
+ RDF::Vocabulary.limit_vocabs(:rdf, :rdf, :schema)
39
+
40
+ will limit the vocabularies which are returned from `RDF::Vocabulary.each`, which is used for reasoning and other operations over vocabularies and terms.
41
+
25
42
  ## Examples
26
43
  ### Determine super-classes of a class
27
44
 
@@ -104,8 +121,8 @@ The `rdf` command-line interface is extended with `entail` and `lint` commands.
104
121
 
105
122
  ## Dependencies
106
123
 
107
- * [Ruby](https://ruby-lang.org/) (>= 2.2.2)
108
- * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.0)
124
+ * [Ruby](https://ruby-lang.org/) (>= 2.4)
125
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.1)
109
126
 
110
127
  ## Mailing List
111
128
 
@@ -128,7 +145,9 @@ The `rdf` command-line interface is extended with `entail` and `lint` commands.
128
145
  list in the the `README`. Alphabetical order applies.
129
146
  * Do note that in order for us to merge any non-trivial changes (as a rule
130
147
  of thumb, additions larger than about 15 lines of code), we need an
131
- explicit [public domain dedication][PDD] on record from you.
148
+ explicit [public domain dedication][PDD] on record from you,
149
+ which you will be asked to agree to on the first commit to a repo within the organization.
150
+ Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
132
151
 
133
152
  ## License
134
153
 
@@ -139,7 +158,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
139
158
  [RDF]: https://www.w3.org/RDF/
140
159
  [YARD]: https://yardoc.org/
141
160
  [YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
142
- [PDD]: https://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
161
+ [PDD]: https://unlicense.org/#unlicensing-contributions
143
162
  [SPARQL]: https://en.wikipedia.org/wiki/SPARQL
144
163
  [SPARQL Query]: https://www.w3.org/TR/2013/REC-sparql11-query-20130321/
145
164
  [SPARQL Entailment]:https://www.w3.org/TR/sparql11-entailment/
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.5.3
1
+ 0.7.1
data/lib/rdf/reasoner.rb CHANGED
@@ -1,12 +1,11 @@
1
1
  require 'rdf'
2
2
  require 'rdf/reasoner/extensions'
3
- require 'rdf/vocab'
4
3
 
5
4
  module RDF
6
5
  ##
7
6
  # RDFS/OWL reasonsing for RDF.rb.
8
7
  #
9
- # @see http://www.w3.org/TR/2013/REC-sparql11-entailment-20130321/
8
+ # @see https://www.w3.org/TR/2013/REC-sparql11-entailment-20130321/
10
9
  # @author [Gregg Kellogg](https://greggkellogg.net/)
11
10
  module Reasoner
12
11
  require 'rdf/reasoner/format'
@@ -15,7 +14,7 @@ module RDF
15
14
  autoload :Schema, 'rdf/reasoner/schema'
16
15
  autoload :VERSION, 'rdf/reasoner/version'
17
16
 
18
- # See http://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/
17
+ # See https://www.pelagodesign.com/blog/2009/05/20/iso-8601-date-validation-that-doesnt-suck/
19
18
  #
20
19
  #
21
20
  ISO_8601 = %r(^
@@ -91,7 +91,7 @@ module RDF
91
91
  # Fully entailed types of resource, if not provided, they are queried
92
92
  def domain_compatible?(resource, queryable, options = {})
93
93
  %w(owl rdfs schema).map {|r| "domain_compatible_#{r}?".to_sym}.all? do |meth|
94
- !self.respond_to?(meth) || self.send(meth, resource, queryable, options)
94
+ !self.respond_to?(meth) || self.send(meth, resource, queryable, **options)
95
95
  end
96
96
  end
97
97
 
@@ -233,7 +233,7 @@ module RDF
233
233
  messages = {}
234
234
 
235
235
  # Check for defined classes in known vocabularies
236
- self.query(predicate: RDF.type) do |stmt|
236
+ self.query({predicate: RDF.type}) do |stmt|
237
237
  vocab = RDF::Vocabulary.find(stmt.object)
238
238
  term = (RDF::Vocabulary.find_term(stmt.object) rescue nil) if vocab
239
239
  pname = term ? term.pname : stmt.object.pname
@@ -241,7 +241,7 @@ module RDF
241
241
  # Must be a defined term, not in RDF or RDFS vocabularies
242
242
  if term && term.class?
243
243
  # Warn against using a deprecated term
244
- superseded = term.attributes[:'schema:supersededBy']
244
+ superseded = term.properties[:'http://schema.org/supersededBy']
245
245
  superseded = superseded.pname if superseded.respond_to?(:pname)
246
246
  (messages[:class] ||= {})[pname] = ["Term is superseded by #{superseded}"] if superseded
247
247
  else
@@ -264,9 +264,9 @@ module RDF
264
264
  end
265
265
 
266
266
  # Must be a defined property
267
- if term && term.property?
267
+ if term.respond_to?(:property?) && term.property?
268
268
  # Warn against using a deprecated term
269
- superseded = term.attributes[:'schema:supersededBy']
269
+ superseded = term.properties[:'http://schema.org/supersededBy']
270
270
  superseded = superseded.pname if superseded.respond_to?(:pname)
271
271
  (messages[:property] ||= {})[pname] = ["Term is superseded by #{superseded}"] if superseded
272
272
  else
@@ -275,7 +275,7 @@ module RDF
275
275
  end
276
276
 
277
277
  # See if type of the subject is in the domain of this predicate
278
- resource_types[stmt.subject] ||= self.query(subject: stmt.subject, predicate: RDF.type).
278
+ resource_types[stmt.subject] ||= self.query({subject: stmt.subject, predicate: RDF.type}).
279
279
  map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
280
280
  flatten.
281
281
  uniq.
@@ -290,7 +290,7 @@ module RDF
290
290
  end
291
291
 
292
292
  # Make sure that if ranges are defined, the object has an appropriate type
293
- resource_types[stmt.object] ||= self.query(subject: stmt.object, predicate: RDF.type).
293
+ resource_types[stmt.object] ||= self.query({subject: stmt.object, predicate: RDF.type}).
294
294
  map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
295
295
  flatten.
296
296
  uniq.
@@ -316,7 +316,7 @@ module RDF
316
316
  def show_resource(resource)
317
317
  if resource.node?
318
318
  resource.to_ntriples + '(' +
319
- self.query(subject: resource, predicate: RDF.type).
319
+ self.query({subject: resource, predicate: RDF.type}).
320
320
  map {|s| s.object.uri? ? s.object.pname : s.object.to_ntriples}
321
321
  .join(',') +
322
322
  ')'
@@ -50,7 +50,7 @@ module RDF::Reasoner
50
50
  if self.predicate == RDF.type
51
51
  if term = (RDF::Vocabulary.find_term(self.object) rescue nil)
52
52
  term._entail_equivalentClass do |t|
53
- statements << RDF::Statement(self.to_h.merge(object: t, inferred: true))
53
+ statements << RDF::Statement(**self.to_h.merge(object: t, inferred: true))
54
54
  end
55
55
  end
56
56
  end
@@ -89,7 +89,7 @@ module RDF::Reasoner
89
89
  statements = []
90
90
  if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
91
91
  term._entail_equivalentProperty do |t|
92
- statements << RDF::Statement(self.to_h.merge(predicate: t, inferred: true))
92
+ statements << RDF::Statement(**self.to_h.merge(predicate: t, inferred: true))
93
93
  end
94
94
  end
95
95
  statements.each {|s| yield s} if block_given?
@@ -74,7 +74,7 @@ module RDF::Reasoner
74
74
  if term = (RDF::Vocabulary.find_term(self.object) rescue nil)
75
75
  term._entail_subClassOf do |t|
76
76
  next if t.node? # Don't entail BNodes
77
- statements << RDF::Statement(self.to_h.merge(object: t, inferred: true))
77
+ statements << RDF::Statement(**self.to_h.merge(object: t, inferred: true))
78
78
  end
79
79
  end
80
80
  #$stderr.puts("subClassf(#{self.predicate.pname}): #{statements.map(&:object).map {|r| r.respond_to?(:pname) ? r.pname : r.to_ntriples}}}")
@@ -122,7 +122,7 @@ module RDF::Reasoner
122
122
 
123
123
  ##
124
124
  # For a Term: yield or return inferred subPropertyOf relationships by recursively applying to named super classes to get a complete set of classes in the ancestor chain of this class
125
- # For a Statement: yield or return inferred statements having a subPropertyOf relationship to predicate of this statement
125
+ # For a Statement: yield or return inferred statements having a subPropertyOf relationship to predicate of this statements
126
126
  # @private
127
127
  def _entail_subPropertyOf
128
128
  case self
@@ -143,7 +143,7 @@ module RDF::Reasoner
143
143
  statements = []
144
144
  if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
145
145
  term._entail_subPropertyOf do |t|
146
- statements << RDF::Statement(self.to_h.merge(predicate: t, inferred: true))
146
+ statements << RDF::Statement(**self.to_h.merge(predicate: t, inferred: true))
147
147
  end
148
148
  #$stderr.puts("subPropertyOf(#{self.predicate.pname}): #{statements.map(&:object).map {|r| r.respond_to?(:pname) ? r.pname : r.to_ntriples}}}")
149
149
  end
@@ -208,7 +208,7 @@ module RDF::Reasoner
208
208
  if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
209
209
  term.domain.each do |t|
210
210
  next if t.node? # Don't entail BNodes
211
- statements << RDF::Statement(self.to_h.merge(predicate: RDF.type, object: t, inferred: true))
211
+ statements << RDF::Statement(**self.to_h.merge(predicate: RDF.type, object: t, inferred: true))
212
212
  end
213
213
  end
214
214
  #$stderr.puts("domain(#{self.predicate.pname}): #{statements.map(&:object).map {|r| r.respond_to?(:pname) ? r.pname : r.to_ntriples}}}")
@@ -229,7 +229,7 @@ module RDF::Reasoner
229
229
  if object.resource? && term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
230
230
  term.range.each do |t|
231
231
  next if t.node? # Don't entail BNodes
232
- statements << RDF::Statement(self.to_h.merge(subject: self.object, predicate: RDF.type, object: t, inferred: true))
232
+ statements << RDF::Statement(**self.to_h.merge(subject: self.object, predicate: RDF.type, object: t, inferred: true))
233
233
  end
234
234
  end
235
235
  #$stderr.puts("range(#{self.predicate.pname}): #{statements.map(&:object).map {|r| r.respond_to?(:pname) ? r.pname : r.to_ntriples}}")
@@ -255,7 +255,7 @@ module RDF::Reasoner
255
255
 
256
256
  # Fully entailed types of the resource
257
257
  types = options.fetch(:types) do
258
- queryable.query(subject: resource, predicate: RDF.type).
258
+ queryable.query({subject: resource, predicate: RDF.type}).
259
259
  map {|s| (t = (RDF::Vocabulary.find_term(s.object)) rescue nil) && t.entail(:subClassOf)}.
260
260
  flatten.
261
261
  uniq.
@@ -290,12 +290,12 @@ module RDF::Reasoner
290
290
  # XSD types are valid if the datatype matches, or they are plain and valid according to the grammar of the range
291
291
  resource.datatype == range ||
292
292
  resource.plain? && RDF::Literal.new(resource.value, datatype: range).valid?
293
- elsif range.start_with?(RDF::Vocab::OGC)
293
+ elsif range.start_with?("http://ogp.me/ns/class#")
294
294
  case range
295
- when RDF::Vocab::OGC.boolean_str
296
- [RDF::Vocab::OGC.boolean_str, RDF::XSD.boolean].include?(resource.datatype) ||
295
+ when RDF::URI("http://ogp.me/ns/class#boolean_str")
296
+ [RDF::URI("http://ogp.me/ns/class#boolean_str"), RDF::XSD.boolean].include?(resource.datatype) ||
297
297
  resource.plain? && RDF::Literal::Boolean.new(resource.value).valid?
298
- when RDF::Vocab::OGC.date_time_str
298
+ when RDF::URI("http://ogp.me/ns/class#date_time_str")
299
299
  # Schema.org date based on ISO 8601, mapped to appropriate XSD types for validation
300
300
  case resource
301
301
  when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime, RDF::Literal::Duration
@@ -303,27 +303,27 @@ module RDF::Reasoner
303
303
  else
304
304
  ISO_8601.match(resource.value)
305
305
  end
306
- when RDF::Vocab::OGC.determiner_str
306
+ when RDF::URI("http://ogp.me/ns/class#determiner_str")
307
307
  # The lexical space: "", "the", "a", "an", and "auto".
308
308
  resource.plain? && (%w(the a an auto) + [""]).include?(resource.value)
309
- when RDF::Vocab::OGC.float_str
309
+ when RDF::URI("http://ogp.me/ns/class#float_str")
310
310
  # A string representation of a 64-bit signed floating point number. Example lexical values include "1.234", "-1.234", "1.2e3", "-1.2e3", and "7E-10".
311
- [RDF::Vocab::OGC.float_str, RDF::Literal::Double, RDF::Literal::Float].include?(resource.datatype) ||
311
+ [RDF::URI("http://ogp.me/ns/class#float_str"), RDF::Literal::Double, RDF::Literal::Float].include?(resource.datatype) ||
312
312
  resource.plain? && RDF::Literal::Double.new(resource.value).valid?
313
- when RDF::Vocab::OGC.integer_str
313
+ when RDF::URI("http://ogp.me/ns/class#integer_str")
314
314
  resource.is_a?(RDF::Literal::Integer) ||
315
- [RDF::Vocab::OGC.integer_str].include?(resource.datatype) ||
315
+ [RDF::URI("http://ogp.me/ns/class#integer_str")].include?(resource.datatype) ||
316
316
  resource.plain? && RDF::Literal::Integer.new(resource.value).valid?
317
- when RDF::Vocab::OGC.mime_type_str
317
+ when RDF::URI("http://ogp.me/ns/class#mime_type_str")
318
318
  # Valid mime type strings \(e.g., "application/mp3"\).
319
- [RDF::Vocab::OGC.mime_type_str].include?(resource.datatype) ||
319
+ [RDF::URI("http://ogp.me/ns/class#mime_type_str")].include?(resource.datatype) ||
320
320
  resource.plain? && resource.value =~ %r(^[\w\-\+]+/[\w\-\+]+$)
321
- when RDF::Vocab::OGC.string
321
+ when RDF::URI("http://ogp.me/ns/class#string")
322
322
  resource.plain?
323
- when RDF::Vocab::OGC.url
323
+ when RDF::URI("http://ogp.me/ns/class#url")
324
324
  # A string of Unicode characters forming a valid URL having the http or https scheme.
325
325
  u = RDF::URI(resource.value)
326
- resource.datatype == RDF::Vocab::OGC.url ||
326
+ resource.datatype == RDF::URI("http://ogp.me/ns/class#url") ||
327
327
  resource.datatype == RDF::XSD.anyURI ||
328
328
  resource.simple? && u.valid? && u.scheme.to_s =~ /^https?$/
329
329
  else
@@ -337,7 +337,7 @@ module RDF::Reasoner
337
337
  else
338
338
  # Fully entailed types of the resource
339
339
  types = options.fetch(:types) do
340
- queryable.query(subject: resource, predicate: RDF.type).
340
+ queryable.query({subject: resource, predicate: RDF.type}).
341
341
  map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
342
342
  flatten.
343
343
  uniq.
@@ -24,18 +24,20 @@ module RDF::Reasoner
24
24
  # Fully entailed types of resource, if not provided, they are queried
25
25
  def domain_compatible_schema?(resource, queryable, options = {})
26
26
  raise RDF::Reasoner::Error, "#{self} can't get domains" unless property?
27
- domains = Array(self.domainIncludes) - [RDF::OWL.Thing]
27
+ domains = Array(self.domainIncludes) +
28
+ Array(self.properties[:'https://schema.org/domainIncludes']) -
29
+ [RDF::OWL.Thing]
28
30
 
29
31
  # Fully entailed types of the resource
30
- types = entailed_types(resource, queryable, options) unless domains.empty?
32
+ types = entailed_types(resource, queryable, **options) unless domains.empty?
31
33
 
32
34
  # Every domain must match some entailed type
33
35
  resource_acceptable = Array(types).empty? || domains.any? {|d| types.include?(d)}
34
36
 
35
37
  # Resource may still be acceptable if types include schema:Role, and any any other resource references `resource` using this property
36
38
  resource_acceptable ||
37
- types.include?(RDF::Vocab::SCHEMA.Role) &&
38
- !queryable.query(predicate: self, object: resource).empty?
39
+ (types.include?(RDF::URI("http://schema.org/Role")) || types.include?(RDF::URI("https://schema.org/Role"))) &&
40
+ !queryable.query({predicate: self, object: resource}).empty?
39
41
  end
40
42
 
41
43
  ##
@@ -54,16 +56,23 @@ module RDF::Reasoner
54
56
  # Fully entailed types of resource, if not provided, they are queried
55
57
  def range_compatible_schema?(resource, queryable, options = {})
56
58
  raise RDF::Reasoner::Error, "#{self} can't get ranges" unless property?
57
- if !(ranges = Array(self.rangeIncludes) - [RDF::OWL.Thing]).empty?
59
+ if !(ranges = Array(self.rangeIncludes) +
60
+ Array(self.properties[:'https://schema.org/rangeIncludes']) -
61
+ [RDF::OWL.Thing]).empty?
58
62
  if resource.literal?
59
63
  ranges.any? do |range|
60
64
  case range
61
65
  when RDF::RDFS.Literal then true
62
- when RDF::Vocab::SCHEMA.Text then resource.plain? || resource.datatype == RDF::Vocab::SCHEMA.Text
63
- when RDF::Vocab::SCHEMA.Boolean
64
- [RDF::Vocab::SCHEMA.Boolean, RDF::XSD.boolean].include?(resource.datatype) ||
66
+ when RDF::URI("http://schema.org/Text"), RDF::URI("https://schema.org/Text")
67
+ resource.plain? || resource.datatype == RDF::URI("http://schema.org/Text")
68
+ when RDF::URI("http://schema.org/Boolean"), RDF::URI("https://schema.org/Boolean")
69
+ [
70
+ RDF::URI("http://schema.org/Boolean"),
71
+ RDF::URI("https://schema.org/Boolean"),
72
+ RDF::XSD.boolean
73
+ ].include?(resource.datatype) ||
65
74
  resource.plain? && RDF::Literal::Boolean.new(resource.value).valid?
66
- when RDF::Vocab::SCHEMA.Date
75
+ when RDF::URI("http://schema.org/Date"), RDF::URI("https://schema.org/Date")
67
76
  # Schema.org date based on ISO 8601, mapped to appropriate XSD types for validation
68
77
  case resource
69
78
  when RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime, RDF::Literal::Duration
@@ -71,35 +80,56 @@ module RDF::Reasoner
71
80
  else
72
81
  ISO_8601.match(resource.value)
73
82
  end
74
- when RDF::Vocab::SCHEMA.DateTime
75
- resource.datatype == RDF::Vocab::SCHEMA.DateTime ||
83
+ when RDF::URI("http://schema.org/DateTime"), RDF::URI("https://schema.org/DateTime")
84
+ resource.datatype == RDF::URI("http://schema.org/DateTime") ||
85
+ resource.datatype == RDF::URI("https://schema.org/DateTime") ||
76
86
  resource.is_a?(RDF::Literal::DateTime) ||
77
87
  resource.plain? && RDF::Literal::DateTime.new(resource.value).valid?
78
- when RDF::Vocab::SCHEMA.Duration
88
+ when RDF::URI("http://schema.org/Duration"), RDF::URI("https://schema.org/Duration")
79
89
  value = resource.value
80
90
  value = "P#{value}" unless value.start_with?("P")
81
- resource.datatype == RDF::Vocab::SCHEMA.Duration ||
91
+ resource.datatype == RDF::URI("http://schema.org/Duration") ||
92
+ resource.datatype == RDF::URI("https://schema.org/Duration") ||
82
93
  resource.is_a?(RDF::Literal::Duration) ||
83
94
  resource.plain? && RDF::Literal::Duration.new(value).valid?
84
- when RDF::Vocab::SCHEMA.Time
85
- resource.datatype == RDF::Vocab::SCHEMA.Time ||
95
+ when RDF::URI("http://schema.org/Time"), RDF::URI("https://schema.org/Time")
96
+ resource.datatype == RDF::URI("http://schema.org/Time") ||
97
+ resource.datatype == RDF::URI("https://schema.org/Time") ||
86
98
  resource.is_a?(RDF::Literal::Time) ||
87
99
  resource.plain? && RDF::Literal::Time.new(resource.value).valid?
88
- when RDF::Vocab::SCHEMA.Number
100
+ when RDF::URI("http://schema.org/Number"), RDF::URI("https://schema.org/Number")
89
101
  resource.is_a?(RDF::Literal::Numeric) ||
90
- [RDF::Vocab::SCHEMA.Number, RDF::Vocab::SCHEMA.Float, RDF::Vocab::SCHEMA.Integer].include?(resource.datatype) ||
102
+ [
103
+ RDF::URI("http://schema.org/Number"),
104
+ RDF::URI("http://schema.org/Float"),
105
+ RDF::URI("http://schema.org/Integer"),
106
+ RDF::URI("https://schema.org/Number"),
107
+ RDF::URI("https://schema.org/Float"),
108
+ RDF::URI("https://schema.org/Integer"),
109
+ ].include?(resource.datatype) ||
91
110
  resource.plain? && RDF::Literal::Integer.new(resource.value).valid? ||
92
111
  resource.plain? && RDF::Literal::Double.new(resource.value).valid?
93
- when RDF::Vocab::SCHEMA.Float
112
+ when RDF::URI("http://schema.org/Float"), RDF::URI("https://schema.org/Float")
94
113
  resource.is_a?(RDF::Literal::Double) ||
95
- [RDF::Vocab::SCHEMA.Number, RDF::Vocab::SCHEMA.Float].include?(resource.datatype) ||
114
+ [
115
+ RDF::URI("http://schema.org/Number"),
116
+ RDF::URI("http://schema.org/Float"),
117
+ RDF::URI("https://schema.org/Number"),
118
+ RDF::URI("https://schema.org/Float"),
119
+ ].include?(resource.datatype) ||
96
120
  resource.plain? && RDF::Literal::Double.new(resource.value).valid?
97
- when RDF::Vocab::SCHEMA.Integer
121
+ when RDF::URI("http://schema.org/Integer"), RDF::URI("https://schema.org/Integer")
98
122
  resource.is_a?(RDF::Literal::Integer) ||
99
- [RDF::Vocab::SCHEMA.Number, RDF::Vocab::SCHEMA.Integer].include?(resource.datatype) ||
123
+ [
124
+ RDF::URI("http://schema.org/Number"),
125
+ RDF::URI("http://schema.org/Integer"),
126
+ RDF::URI("https://schema.org/Number"),
127
+ RDF::URI("https://schema.org/Integer"),
128
+ ].include?(resource.datatype) ||
100
129
  resource.plain? && RDF::Literal::Integer.new(resource.value).valid?
101
- when RDF::Vocab::SCHEMA.URL
102
- resource.datatype == RDF::Vocab::SCHEMA.URL ||
130
+ when RDF::URI("http://schema.org/URL"), RDF::URI("https://schema.org/URL")
131
+ resource.datatype == RDF::URI("http://schema.org/URL") ||
132
+ resource.datatype == RDF::URI("https://schema.org/URL") ||
103
133
  resource.datatype == RDF::XSD.anyURI ||
104
134
  resource.plain? && RDF::Literal::AnyURI.new(resource.value).valid?
105
135
  else
@@ -117,18 +147,28 @@ module RDF::Reasoner
117
147
  end
118
148
  end
119
149
  end
120
- elsif %w(True False).map {|v| RDF::Vocab::SCHEMA[v]}.include?(resource) && ranges.include?(RDF::Vocab::SCHEMA.Boolean)
150
+ elsif %w(
151
+ http://schema.org/True
152
+ http://schema.org/False
153
+ https://schema.org/True
154
+ https://schema.org/False
155
+ ).include?(resource) &&
156
+ (ranges.include?(RDF::URI("http://schema.org/Boolean")) || ranges.include?(RDF::URI("https://schema.org/Boolean")))
121
157
  true # Special case for schema boolean resources
122
- elsif ranges.include?(RDF::Vocab::SCHEMA.URL) && resource.uri?
158
+ elsif (ranges.include?(RDF::URI("http://schema.org/URL")) || ranges.include?(RDF::URI("https://schema.org/URL"))) &&
159
+ resource.uri?
123
160
  true # schema:URL matches URI resources
124
- elsif ranges == [RDF::Vocab::SCHEMA.Text] && resource.uri?
161
+ elsif ranges == [RDF::URI("http://schema.org/Text")] && resource.uri?
125
162
  # Allowed if resource is untyped
126
- entailed_types(resource, queryable, options).empty?
163
+ entailed_types(resource, queryable, **options).empty?
164
+ elsif ranges == [RDF::URI("https://schema.org/Text")] && resource.uri?
165
+ # Allowed if resource is untyped
166
+ entailed_types(resource, queryable, **options).empty?
127
167
  elsif literal_range?(ranges)
128
168
  false # If resource isn't literal, this is a range violation
129
169
  else
130
170
  # Fully entailed types of the resource
131
- types = entailed_types(resource, queryable, options)
171
+ types = entailed_types(resource, queryable, **options)
132
172
 
133
173
  # Every range must match some entailed type
134
174
  resource_acceptable = Array(types).empty? || ranges.any? {|d| types.include?(d)}
@@ -137,8 +177,8 @@ module RDF::Reasoner
137
177
  resource_acceptable ||
138
178
 
139
179
  # Resource also acceptable if it is a Role, and the Role object contains the same predicate having a compatible object
140
- types.include?(RDF::Vocab::SCHEMA.Role) &&
141
- queryable.query(subject: resource, predicate: self).any? do |stmt|
180
+ (types.include?(RDF::URI("http://schema.org/Role")) || types.include?(RDF::URI("https://schema.org/Role"))) &&
181
+ queryable.query({subject: resource, predicate: self}).any? do |stmt|
142
182
  acc = self.range_compatible_schema?(stmt.object, queryable)
143
183
  acc
144
184
  end ||
@@ -158,9 +198,25 @@ module RDF::Reasoner
158
198
  def literal_range?(ranges)
159
199
  ranges.all? do |range|
160
200
  case range
161
- when RDF::RDFS.Literal, RDF::Vocab::SCHEMA.Text, RDF::Vocab::SCHEMA.Boolean, RDF::Vocab::SCHEMA.Date,
162
- RDF::Vocab::SCHEMA.DateTime, RDF::Vocab::SCHEMA.Time, RDF::Vocab::SCHEMA.URL,
163
- RDF::Vocab::SCHEMA.Number, RDF::Vocab::SCHEMA.Float, RDF::Vocab::SCHEMA.Integer
201
+ when RDF::RDFS.Literal,
202
+ RDF::URI("http://schema.org/Text"),
203
+ RDF::URI("http://schema.org/Boolean"),
204
+ RDF::URI("http://schema.org/Date"),
205
+ RDF::URI("http://schema.org/DateTime"),
206
+ RDF::URI("http://schema.org/Time"),
207
+ RDF::URI("http://schema.org/URL"),
208
+ RDF::URI("http://schema.org/Number"),
209
+ RDF::URI("http://schema.org/Float"),
210
+ RDF::URI("http://schema.org/Integer"),
211
+ RDF::URI("https://schema.org/Text"),
212
+ RDF::URI("https://schema.org/Boolean"),
213
+ RDF::URI("https://schema.org/Date"),
214
+ RDF::URI("https://schema.org/DateTime"),
215
+ RDF::URI("https://schema.org/Time"),
216
+ RDF::URI("https://schema.org/URL"),
217
+ RDF::URI("https://schema.org/Number"),
218
+ RDF::URI("https://schema.org/Float"),
219
+ RDF::URI("https://schema.org/Integer")
164
220
  true
165
221
  else
166
222
  # If this is an XSD range, look for appropriate literal
@@ -174,9 +230,9 @@ module RDF::Reasoner
174
230
 
175
231
  private
176
232
  # Fully entailed types
177
- def entailed_types(resource, queryable, options = {})
233
+ def entailed_types(resource, queryable, **options)
178
234
  options.fetch(:types) do
179
- queryable.query(subject: resource, predicate: RDF.type).
235
+ queryable.query({subject: resource, predicate: RDF.type}).
180
236
  map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
181
237
  flatten.
182
238
  uniq.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-reasoner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-12 00:00:00.000000000 Z
11
+ date: 2021-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -16,84 +16,96 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '3.1'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 3.1.12
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '3.0'
29
+ version: '3.1'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 3.1.12
27
33
  - !ruby/object:Gem::Dependency
28
- name: rdf-vocab
34
+ name: rdf-xsd
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '3.0'
39
+ version: '3.1'
34
40
  type: :runtime
35
41
  prerelease: false
36
42
  version_requirements: !ruby/object:Gem::Requirement
37
43
  requirements:
38
44
  - - "~>"
39
45
  - !ruby/object:Gem::Version
40
- version: '3.0'
46
+ version: '3.1'
41
47
  - !ruby/object:Gem::Dependency
42
- name: rdf-xsd
48
+ name: rdf-spec
43
49
  requirement: !ruby/object:Gem::Requirement
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :runtime
53
+ version: '3.1'
54
+ type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '3.0'
60
+ version: '3.1'
55
61
  - !ruby/object:Gem::Dependency
56
- name: rdf-spec
62
+ name: rdf-vocab
57
63
  requirement: !ruby/object:Gem::Requirement
58
64
  requirements:
59
65
  - - "~>"
60
66
  - !ruby/object:Gem::Version
61
- version: '3.0'
67
+ version: '3.1'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 3.1.10
62
71
  type: :development
63
72
  prerelease: false
64
73
  version_requirements: !ruby/object:Gem::Requirement
65
74
  requirements:
66
75
  - - "~>"
67
76
  - !ruby/object:Gem::Version
68
- version: '3.0'
77
+ version: '3.1'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 3.1.10
69
81
  - !ruby/object:Gem::Dependency
70
82
  name: rdf-turtle
71
83
  requirement: !ruby/object:Gem::Requirement
72
84
  requirements:
73
85
  - - "~>"
74
86
  - !ruby/object:Gem::Version
75
- version: '3.0'
87
+ version: '3.1'
76
88
  type: :development
77
89
  prerelease: false
78
90
  version_requirements: !ruby/object:Gem::Requirement
79
91
  requirements:
80
92
  - - "~>"
81
93
  - !ruby/object:Gem::Version
82
- version: '3.0'
94
+ version: '3.1'
83
95
  - !ruby/object:Gem::Dependency
84
96
  name: json-ld
85
97
  requirement: !ruby/object:Gem::Requirement
86
98
  requirements:
87
99
  - - "~>"
88
100
  - !ruby/object:Gem::Version
89
- version: '3.0'
101
+ version: '3.1'
90
102
  type: :development
91
103
  prerelease: false
92
104
  version_requirements: !ruby/object:Gem::Requirement
93
105
  requirements:
94
106
  - - "~>"
95
107
  - !ruby/object:Gem::Version
96
- version: '3.0'
108
+ version: '3.1'
97
109
  - !ruby/object:Gem::Dependency
98
110
  name: equivalent-xml
99
111
  requirement: !ruby/object:Gem::Requirement
@@ -114,28 +126,28 @@ dependencies:
114
126
  requirements:
115
127
  - - "~>"
116
128
  - !ruby/object:Gem::Version
117
- version: '3.8'
129
+ version: '3.10'
118
130
  type: :development
119
131
  prerelease: false
120
132
  version_requirements: !ruby/object:Gem::Requirement
121
133
  requirements:
122
134
  - - "~>"
123
135
  - !ruby/object:Gem::Version
124
- version: '3.8'
136
+ version: '3.10'
125
137
  - !ruby/object:Gem::Dependency
126
138
  name: yard
127
139
  requirement: !ruby/object:Gem::Requirement
128
140
  requirements:
129
141
  - - "~>"
130
142
  - !ruby/object:Gem::Version
131
- version: 0.9.19
143
+ version: '0.9'
132
144
  type: :development
133
145
  prerelease: false
134
146
  version_requirements: !ruby/object:Gem::Requirement
135
147
  requirements:
136
148
  - - "~>"
137
149
  - !ruby/object:Gem::Version
138
- version: 0.9.19
150
+ version: '0.9'
139
151
  description: Reasons over RDFS/OWL vocabularies to generate statements which are entailed
140
152
  based on base RDFS/OWL rules along with vocabulary information. It can also be used
141
153
  to ask specific questions, such as if a given object is consistent with the vocabulary
@@ -160,7 +172,7 @@ homepage: https://github.com/ruby-rdf/rdf-reasoner
160
172
  licenses:
161
173
  - Unlicense
162
174
  metadata: {}
163
- post_install_message:
175
+ post_install_message:
164
176
  rdoc_options: []
165
177
  require_paths:
166
178
  - lib
@@ -168,15 +180,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
180
  requirements:
169
181
  - - ">="
170
182
  - !ruby/object:Gem::Version
171
- version: 2.2.2
183
+ version: '2.4'
172
184
  required_rubygems_version: !ruby/object:Gem::Requirement
173
185
  requirements:
174
186
  - - ">="
175
187
  - !ruby/object:Gem::Version
176
188
  version: '0'
177
189
  requirements: []
178
- rubygems_version: 3.0.4
179
- signing_key:
190
+ rubygems_version: 3.2.3
191
+ signing_key:
180
192
  specification_version: 4
181
193
  summary: RDFS/OWL Reasoner for RDF.rb
182
194
  test_files: []