rdf-reasoner 0.1.0 → 0.2.0
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.
- data/README.md +64 -0
- data/VERSION +1 -1
- data/lib/rdf/reasoner.rb +1 -1
- data/lib/rdf/reasoner/extensions.rb +156 -40
- data/lib/rdf/reasoner/owl.rb +112 -317
- data/lib/rdf/reasoner/rdfs.rb +122 -17
- data/lib/rdf/reasoner/schema.rb +2 -2
- metadata +40 -24
- checksums.yaml +0 -7
data/README.md
CHANGED
@@ -6,7 +6,10 @@ Reasons over RDFS/OWL vocabularies and schema.org to generate statements which a
|
|
6
6
|
|
7
7
|
* Entail `rdfs:subClassOf` generating an array of terms which are ancestors of the subject.
|
8
8
|
* Entail `rdfs:subPropertyOf` generating an array of terms which are ancestors of the subject.
|
9
|
+
* Entail `rdfs:domain` and `rdfs:range` adding `rdf:type` assertions on the subject or object.
|
9
10
|
* Inverse `rdfs:subClassOf` entailment, to find descendant classes of the subject term.
|
11
|
+
* Entail `owl:equivalentClass` generating an array of terms equivalent to the subject.
|
12
|
+
* Entail `owl:equivalentProperty` generating an array of terms equivalent to the subject.
|
10
13
|
* `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.
|
11
14
|
* `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.
|
12
15
|
|
@@ -17,6 +20,67 @@ Domain and Range entailment include specific rules for schema.org vocabularies.
|
|
17
20
|
* If `resource` is of type `schema:Role`, it is range acceptable if it has the same property with an acceptable value.
|
18
21
|
* 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.
|
19
22
|
|
23
|
+
## Examples
|
24
|
+
### Determine super-classes of a class
|
25
|
+
|
26
|
+
require 'rdf/reasoner'
|
27
|
+
|
28
|
+
RDF::Reasoner.apply(:rdfs)
|
29
|
+
term = RDF::Vocabulary.find_term("http://xmlns.com/foaf/0.1/Person")
|
30
|
+
term.entail(:subClassOf)
|
31
|
+
# => [
|
32
|
+
foaf:Agent,
|
33
|
+
http://www.w3.org/2000/10/swap/pim/contact#Person,
|
34
|
+
geo:SpatialThing,
|
35
|
+
foaf:Person
|
36
|
+
]
|
37
|
+
|
38
|
+
### Determine sub-classes of a class
|
39
|
+
|
40
|
+
require 'rdf/reasoner'
|
41
|
+
|
42
|
+
RDF::Reasoner.apply(:rdfs)
|
43
|
+
term = RDF::FOAF.Person
|
44
|
+
term.entail(:subClass) # => [foaf:Person, mo:SoloMusicArtist]
|
45
|
+
|
46
|
+
### Determine if a resource is compatible with the domains of a property
|
47
|
+
|
48
|
+
require 'rdf/reasoner'
|
49
|
+
require 'rdf/turtle'
|
50
|
+
|
51
|
+
RDF::Reasoner.apply(:rdfs)
|
52
|
+
graph = RDF::Graph.load("etc/doap.ttl")
|
53
|
+
subj = RDF::URI("http://rubygems.org/gems/rdf-reasoner")
|
54
|
+
RDF::DOAP.name.domain_compatible?(subj, graph) # => true
|
55
|
+
|
56
|
+
### Determine if a resource is compatible with the ranges of a property
|
57
|
+
|
58
|
+
require 'rdf/reasoner'
|
59
|
+
require 'rdf/turtle'
|
60
|
+
|
61
|
+
RDF::Reasoner.apply(:rdfs)
|
62
|
+
graph = RDF::Graph.load("etc/doap.ttl")
|
63
|
+
obj = RDF::Literal(Date.new)
|
64
|
+
RDF::DOAP.created.range_compatible?(obj, graph) # => true
|
65
|
+
|
66
|
+
### Perform equivalentClass entailment on a graph
|
67
|
+
|
68
|
+
require 'rdf/reasoner'
|
69
|
+
require 'rdf/turtle'
|
70
|
+
|
71
|
+
RDF::Reasoner.apply(::owl)
|
72
|
+
graph = RDF::Graph.load("etc/doap.ttl")
|
73
|
+
graph.entail!(:equivalentClass)
|
74
|
+
|
75
|
+
### Yield all entailed statements for all entailment methods
|
76
|
+
|
77
|
+
require 'rdf/reasoner'
|
78
|
+
require 'rdf/turtle'
|
79
|
+
|
80
|
+
RDF::Reasoner.apply(:rdfs, :owl)
|
81
|
+
graph = RDF::Graph.load("etc/doap.ttl")
|
82
|
+
graph.enum_statement.entail.count # >= graph.enum_statement.count
|
83
|
+
|
20
84
|
## Dependencies
|
21
85
|
|
22
86
|
* [Ruby](http://ruby-lang.org/) (>= 1.9.2)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
data/lib/rdf/reasoner.rb
CHANGED
@@ -1,55 +1,171 @@
|
|
1
1
|
# Extensions to RDF core classes to support reasoning
|
2
2
|
require 'rdf'
|
3
3
|
|
4
|
-
|
5
|
-
class
|
6
|
-
|
4
|
+
module RDF
|
5
|
+
class Vocabulary::Term
|
6
|
+
class << self
|
7
|
+
@@entailments = {}
|
8
|
+
|
9
|
+
##
|
10
|
+
# Add an entailment method. The method accepts no arguments, and returns or yields an array of values associated with the particular entailment method
|
11
|
+
# @param [Symbol] method
|
12
|
+
# @param [Proc] proc
|
13
|
+
def add_entailment(method, proc)
|
14
|
+
@@entailments[method] = proc
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Perform an entailment on this term.
|
20
|
+
#
|
21
|
+
# @param [Symbol] method A registered entailment method
|
22
|
+
# @yield term
|
23
|
+
# @yieldparam [Term] term
|
24
|
+
# @return [Array<Term>]
|
25
|
+
def entail(method, &block)
|
26
|
+
self.send(@@entailments.fetch(method), &block)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Determine if the domain of a property term is consistent with the specified resource in `queryable`.
|
31
|
+
#
|
32
|
+
# @param [RDF::Resource] resource
|
33
|
+
# @param [RDF::Queryable] queryable
|
34
|
+
# @param [Hash{Symbol => Object}] options ({})
|
35
|
+
# @option options [Array<RDF::Vocabulary::Term>] :types
|
36
|
+
# Fully entailed types of resource, if not provided, they are queried
|
37
|
+
def domain_compatible?(resource, queryable, options = {})
|
38
|
+
%w(owl rdfs schema).map {|r| "domain_compatible_#{r}?".to_sym}.all? do |meth|
|
39
|
+
!self.respond_to?(meth) || self.send(meth, resource, queryable, options)
|
40
|
+
end
|
41
|
+
end
|
7
42
|
|
8
43
|
##
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
|
13
|
-
|
44
|
+
# Determine if the range of a property term is consistent with the specified resource in `queryable`.
|
45
|
+
#
|
46
|
+
# Specific entailment regimes should insert themselves before this to apply the appropriate semantic condition
|
47
|
+
#
|
48
|
+
# @param [RDF::Resource] resource
|
49
|
+
# @param [RDF::Queryable] queryable
|
50
|
+
# @param [Hash{Symbol => Object}] options ({})
|
51
|
+
# @option options [Array<RDF::Vocabulary::Term>] :types
|
52
|
+
# Fully entailed types of resource, if not provided, they are queried
|
53
|
+
def range_compatible?(resource, queryable, options = {})
|
54
|
+
%w(owl rdfs schema).map {|r| "range_compatible_#{r}?".to_sym}.all? do |meth|
|
55
|
+
!self.respond_to?(meth) || self.send(meth, resource, queryable, options)
|
56
|
+
end
|
14
57
|
end
|
15
58
|
end
|
16
59
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
60
|
+
class Statement
|
61
|
+
class << self
|
62
|
+
@@entailments = {}
|
63
|
+
|
64
|
+
##
|
65
|
+
# Add an entailment method. The method accepts no arguments, and returns or yields an array of values associated with the particular entailment method
|
66
|
+
# @param [Symbol] method
|
67
|
+
# @param [Proc] proc
|
68
|
+
def add_entailment(method, proc)
|
69
|
+
@@entailments[method] = proc
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Perform an entailment on this term.
|
75
|
+
#
|
76
|
+
# @param [Symbol] method A registered entailment method
|
77
|
+
# @yield term
|
78
|
+
# @yieldparam [Term] term
|
79
|
+
# @return [Array<Term>]
|
80
|
+
def entail(method, &block)
|
81
|
+
self.send(@@entailments.fetch(method), &block)
|
82
|
+
end
|
24
83
|
end
|
25
84
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
85
|
+
module Enumerable
|
86
|
+
class << self
|
87
|
+
@@entailments = {}
|
88
|
+
|
89
|
+
##
|
90
|
+
# Add an entailment method. The method accepts no arguments, and returns or yields an array of values associated with the particular entailment method
|
91
|
+
# @param [Symbol] method
|
92
|
+
# @param [Proc] proc
|
93
|
+
def add_entailment(method, proc)
|
94
|
+
@@entailments[method] = proc
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Perform entailments on this enumerable in a single pass, yielding entailed statements.
|
100
|
+
#
|
101
|
+
# For best results, either run rules separately expanding the enumberated graph, or run repeatedly until no new statements are added to the enumerable containing both original and entailed statements. As `:subClassOf` and `:subPropertyOf` entailments are implicitly recursive, this may not be necessary except for extreme cases.
|
102
|
+
#
|
103
|
+
# @overload entail
|
104
|
+
# @param [Array<Symbol>] *rules Registered entailment method(s)
|
105
|
+
# @yield statement
|
106
|
+
# @yieldparam [RDF::Statement] statement
|
107
|
+
# @return [void]
|
108
|
+
#
|
109
|
+
# @overload entail
|
110
|
+
# @param [Array<Symbol>] *rules Registered entailment method(s)
|
111
|
+
# @return [Enumerator]
|
112
|
+
def entail(*rules, &block)
|
113
|
+
if block_given?
|
114
|
+
rules = @@entailments.keys if rules.empty?
|
115
|
+
|
116
|
+
self.each do |statement|
|
117
|
+
rules.each {|rule| statement.entail(rule, &block)}
|
118
|
+
end
|
119
|
+
else
|
120
|
+
# Otherwise, return an Enumerator with the entailed statements
|
121
|
+
this = self
|
122
|
+
RDF::Queryable::Enumerator.new do |yielder|
|
123
|
+
this.entail(*rules) {|y| yielder << y}
|
124
|
+
end
|
125
|
+
end
|
37
126
|
end
|
38
127
|
end
|
39
128
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
129
|
+
module Mutable
|
130
|
+
class << self
|
131
|
+
@@entailments = {}
|
132
|
+
|
133
|
+
##
|
134
|
+
# Add an entailment method. The method accepts no arguments, and returns or yields an array of values associated with the particular entailment method
|
135
|
+
# @param [Symbol] method
|
136
|
+
# @param [Proc] proc
|
137
|
+
def add_entailment(method, proc)
|
138
|
+
@@entailments[method] = proc
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
# Return a new mutable, composed of original and entailed statements
|
143
|
+
#
|
144
|
+
# @param [Array<Symbol>] *rules Registered entailment method(s)
|
145
|
+
# @return [RDF::Mutable]
|
146
|
+
# @see [RDF::Enumerable#entail]
|
147
|
+
def entail(*rules, &block)
|
148
|
+
self.dup.entail!(*rules)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Add entailed statements to the mutable
|
152
|
+
#
|
153
|
+
# @param [Array<Symbol>] *rules Registered entailment method(s)
|
154
|
+
# @return [RDF::Mutable]
|
155
|
+
# @see [RDF::Enumerable#entail]
|
156
|
+
def entail!(*rules, &block)
|
157
|
+
rules = @@entailments.keys if rules.empty?
|
158
|
+
statements = []
|
159
|
+
|
160
|
+
self.each do |statement|
|
161
|
+
rules.each do |rule|
|
162
|
+
statement.entail(rule) do |st|
|
163
|
+
statements << st
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
self.insert *statements
|
168
|
+
self
|
53
169
|
end
|
54
170
|
end
|
55
|
-
end
|
171
|
+
end
|
data/lib/rdf/reasoner/owl.rb
CHANGED
@@ -4,344 +4,139 @@ module RDF::Reasoner
|
|
4
4
|
##
|
5
5
|
# Rules for generating OWL entailment triples
|
6
6
|
#
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
attr_reader :resource
|
15
|
-
|
16
|
-
# RDF::Enumerable containing entity definition
|
17
|
-
#
|
18
|
-
# #!attribute [r] enumerable
|
19
|
-
# @return [RDF::Enumerable]
|
20
|
-
attr_reader :enumerable
|
21
|
-
|
22
|
-
class << self
|
23
|
-
# Class reader for all defined entities
|
24
|
-
# @!attribute [r] all
|
25
|
-
# @return [Array<Property>]
|
26
|
-
attr_reader :all
|
27
|
-
end
|
28
|
-
|
29
|
-
# Find instance based on this resource
|
30
|
-
# @param [RDF::Resource] resource
|
31
|
-
# @return [Base]
|
32
|
-
def self.find(resource)
|
33
|
-
all.detect {|r| r.resource == resource}
|
34
|
-
end
|
35
|
-
|
36
|
-
##
|
37
|
-
# Create a new entity based on resource within enumerable
|
38
|
-
#
|
39
|
-
# @param [RDF::Resource] resource
|
40
|
-
# @param [RDF::Enumerable] enumerable
|
41
|
-
def initialize(resource, enumerable)
|
42
|
-
@resource, @enumerable = resource, enumerable
|
43
|
-
(Base.all ||= []) << self
|
44
|
-
end
|
45
|
-
|
46
|
-
# Human label of this class
|
47
|
-
# @return [String]
|
48
|
-
def label
|
49
|
-
@label || @resource.split(/\/\#/).last
|
50
|
-
end
|
51
|
-
|
52
|
-
# Infered ranges of the {Restriction} or {Property}
|
53
|
-
# FIXME: This does not account for intersection/union
|
54
|
-
# @return [Array<OwlClass,DataType>]
|
55
|
-
def ranges
|
56
|
-
values = @on_class || @all_values_from || @some_values_from || @on_data_range || @range
|
57
|
-
return [] unless values
|
58
|
-
values.map do |v|
|
59
|
-
v.one_of || v.union_of || ([v] + v.descendant_classes)
|
60
|
-
end.flatten
|
61
|
-
end
|
62
|
-
|
63
|
-
# Is this entity the same as `cls`, or is it a union containing `cls`?
|
64
|
-
# @param [OwlClass] cls
|
65
|
-
# @return [TrueClass, FalseClass]
|
66
|
-
def class_of?(cls)
|
67
|
-
cls == self or union_of.include?(cls)
|
68
|
-
end
|
69
|
-
|
70
|
-
# Override for actual descendant classes
|
71
|
-
# @return [Array]
|
72
|
-
def descendant_classes; []; end
|
73
|
-
|
74
|
-
# Is this a named entity (i.e., not some OWL construction)
|
75
|
-
# @return [TrueClass, FalseClass]
|
76
|
-
def named?
|
77
|
-
@resource.iri?
|
78
|
-
end
|
79
|
-
|
80
|
-
##
|
81
|
-
# Accessors for entity fields
|
82
|
-
#
|
83
|
-
# @overload all_values_from
|
84
|
-
# @return [Array<Base>] reflects owl:allValuesFrom
|
85
|
-
# @overload _cardinality
|
86
|
-
# @return [Integer]
|
87
|
-
# reflects owl:cardinality and owl:qualifiedCardinality.
|
88
|
-
# @see {Restriction#cardinality}
|
89
|
-
# @overload equivalent_property
|
90
|
-
# @return [Array<Property>] reflects owl:equivalentProperty
|
91
|
-
# ...
|
92
|
-
def method_missing(meth, *args)
|
93
|
-
def _access(preds, how)
|
94
|
-
@access ||= {}
|
95
|
-
# Memoize result
|
96
|
-
@access[meth] ||= begin
|
97
|
-
values = []
|
98
|
-
preds.each do |pred|
|
99
|
-
enumerable.query(:subject => resource, :predicate => pred) do |statement|
|
100
|
-
values << statement.object
|
101
|
-
end
|
102
|
-
end
|
103
|
-
case how
|
104
|
-
when true
|
105
|
-
# Value is simply true
|
106
|
-
true
|
107
|
-
when :ary
|
108
|
-
# Translate IRIs into instances of Base
|
109
|
-
values.map {|v| Base.find(v) || v}
|
110
|
-
when :list
|
111
|
-
# Access as list and translate IRIs into instances of Base
|
112
|
-
RDF::List(values.first, enumerable).to_a.map {|v| Base.find(v) || v}
|
113
|
-
when :obj, :int
|
114
|
-
# Take first element of array, and optionally translate to integer
|
115
|
-
how == :int ? values.first.to_i : values.first
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
case :meth
|
121
|
-
when :all_values_from then _access([RDF::OWL::allValuesFrom], :ary)
|
122
|
-
when :_cardinality then _access([RDF::OWL::cardinality, RDF::OWL::qualifiedCardinality], :int)
|
123
|
-
when :domain then _access([RDF::RDFS::domain], :ary)
|
124
|
-
when :equivalent_property then _access([RDF::OWL::equivalentProperty], :ary)
|
125
|
-
when :has_self then _access([RDF::OWL::hasSelf], true)
|
126
|
-
when :has_value then _access([RDF::OWL::hasValue], :ary)
|
127
|
-
when :intersection_of then _access([RDF::OWL::hasSelf], true)
|
128
|
-
when :inverse_of then _access([RDF::OWL::inverseOf], :obj)
|
129
|
-
when :max_cardinality then _access([RDF::OWL::maxCardinality, RDF::OWL::maxQualifiedCardinality], :int)
|
130
|
-
when :min_cardinality then _access([RDF::OWL::minCardinality, RDF::OWL::minQualifiedCardinality], :int)
|
131
|
-
when :one_of then _access([RDF::OWL::oneOf], :list)
|
132
|
-
when :on_class then _access([RDF::OWL::onClass], :obj)
|
133
|
-
when :on_datarange then _access([RDF::OWL::onDatatype], :obj)
|
134
|
-
when :on_property then _access([RDF::OWL::onProperty], :obj)
|
135
|
-
when :range then _access([RDF::RDFS::range], :ary)
|
136
|
-
when :some_values_from then _access([RDF::OWL::someValuesFrom], :ary)
|
137
|
-
when :sub_class_of then _access([RDF::RDFS::subClassOf], :ary)
|
138
|
-
when :sub_property_of then _access([RDF::RDFS::subPropertyOf], :ary)
|
139
|
-
when :union_of then _access([RDF::OWL::unionOf], :list)
|
140
|
-
when :with_restrictions then _access([RDF::OWL::withRestrictions], :list)
|
141
|
-
else
|
142
|
-
super
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
# Entries for owl objects which are Object or Datatype Properties
|
148
|
-
class Property < Base
|
149
|
-
class << self
|
150
|
-
# Class reader for all defined properties
|
151
|
-
# @!attribute [r] all
|
152
|
-
# @return [Array<Property>]
|
153
|
-
attr_reader :all
|
154
|
-
end
|
155
|
-
|
156
|
-
##
|
157
|
-
# Create a new property based on resource within enumerable
|
158
|
-
#
|
159
|
-
# @param [RDF::Resource] resource
|
160
|
-
# @param [RDF::Enumerable] enumerable
|
161
|
-
def initialize(resource, enumerable)
|
162
|
-
super
|
163
|
-
(Property.all ||= []) << self
|
164
|
-
end
|
165
|
-
|
166
|
-
# Infered domains of this property
|
167
|
-
# FIXME: does not account for intersection/union, which is uncomon in domains
|
168
|
-
# @return [Array<OwlClass>]
|
169
|
-
def domains
|
170
|
-
self.domain.map do |v|
|
171
|
-
v.one_of || v.union_of || ([v] + v.descendant_classes)
|
172
|
-
end.flatten.uniq
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
# Does this property have a domain including cls?
|
177
|
-
# The JSON is defined to always represent domain as an array
|
178
|
-
# FIXME: this doesn't deal with intersection
|
179
|
-
# @param [OwlClass] cls
|
180
|
-
# @return [TrueClass, FalseClass]
|
181
|
-
def domain_of?(cls)
|
182
|
-
domain.any? {|dom| dom.class_of?(cls)}
|
183
|
-
end
|
7
|
+
# Extends `RDF::Vocabulary::Term` and `RDF::Statement` with specific entailment capabilities
|
8
|
+
module OWL
|
9
|
+
##
|
10
|
+
# @return [RDF::Util::Cache]
|
11
|
+
# @private
|
12
|
+
def equivalentClass_cache
|
13
|
+
@@subPropertyOf_cache ||= {}
|
184
14
|
end
|
185
|
-
|
186
|
-
|
187
|
-
#
|
188
|
-
|
189
|
-
|
190
|
-
# For restrictions, return any defined cardinality
|
191
|
-
# as an array of \[min, max\] where either max may be `nil`.
|
192
|
-
# Min will always be an integer.
|
193
|
-
# @return [Array<(Integer, Integer)>]
|
194
|
-
def cardinality
|
195
|
-
[(@cardinality || @min_cardinality || 0), (@cardinality || @max_cardinality)]
|
196
|
-
end
|
15
|
+
##
|
16
|
+
# @return [RDF::Util::Cache]
|
17
|
+
# @private
|
18
|
+
def equivalentProperty_cache
|
19
|
+
@@equivalentProperty_cache ||= {}
|
197
20
|
end
|
198
21
|
|
199
|
-
# Entries for owl objects wich are classes
|
200
|
-
class OwlClass < Base
|
201
|
-
class << self
|
202
|
-
# Class accessor for all defined classes
|
203
|
-
# @!attribute [r] all
|
204
|
-
# @return [Array<OwlClass>]
|
205
|
-
attr_reader :all
|
206
|
-
end
|
207
22
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
# @return [Array<OwlClass>]
|
220
|
-
def super_classes
|
221
|
-
@super_class_cache ||= begin
|
222
|
-
# Note in super-class, that this is a direct sub-class
|
223
|
-
sup = self.sub_class_of
|
23
|
+
##
|
24
|
+
# For a Term: yield or return inferred equivalentClass relationships
|
25
|
+
# For a Statement: if predicate is `rdf:types`, yield or return inferred statements having a equivalentClass relationship to the type of this statement
|
26
|
+
# @private
|
27
|
+
def _entail_equivalentClass
|
28
|
+
case self
|
29
|
+
when RDF::Vocabulary::Term
|
30
|
+
unless class? && respond_to?(:equivalentClass)
|
31
|
+
yield self if block_given?
|
32
|
+
return Array(self)
|
33
|
+
end
|
224
34
|
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
when 1 then ored_classes.first
|
233
|
-
else (%w(|) + ored_classes).freeze
|
234
|
-
end
|
35
|
+
# Initialize @equivalentClass_cache by iterating over all defined property terms having an `owl:equivalentClass` attribute and adding the source class as an equivalent of the destination class
|
36
|
+
if equivalentClass_cache.empty?
|
37
|
+
RDF::Vocabulary.each do |v|
|
38
|
+
v.each do |term|
|
39
|
+
term.equivalentClass.each do |equiv|
|
40
|
+
(equivalentClass_cache[equiv] ||= []) << term
|
41
|
+
end if term.class?
|
235
42
|
end
|
236
|
-
end.compact
|
237
|
-
|
238
|
-
case anded_classes.length
|
239
|
-
when 0 then [].freeze
|
240
|
-
when 1 then anded_classes.first
|
241
|
-
else (%w(&) + anded_classes).freeze
|
242
43
|
end
|
243
44
|
end
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
end
|
255
|
-
|
256
|
-
# Return all descendant classes
|
257
|
-
# @return [Array<OwlClass>]
|
258
|
-
def descendant_classes
|
259
|
-
@descendant_classes ||= begin
|
260
|
-
(sub_classes + sub_classes.map {|cls| cls.descendant_classes}.flatten).compact.freeze
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
# Return a list of all property restrictions on this class and super-classes
|
265
|
-
# @return [Array<Restriction>]
|
266
|
-
def property_restrictions
|
267
|
-
@property_restrictions_cache ||= begin
|
268
|
-
restrictions = evaluate_sexp(self.super_classes) {|c| c.property_restrictions}.dup
|
269
|
-
restrictions = [restrictions].compact unless restrictions.is_a?(Array)
|
270
|
-
# Add restrictions defined on this class
|
271
|
-
self.sub_class_of.select {|r| r.is_a?(Restriction)}.each do |restriction|
|
272
|
-
prop = restriction.on_property
|
273
|
-
# Remove any existing restriction on the same property
|
274
|
-
restrictions.reject! {|r| r.on_property == prop}
|
275
|
-
#puts "#{resource}: add local restriction: #{restriction.on_property.resource}"
|
276
|
-
restrictions << restriction
|
45
|
+
terms = (self.equivalentClass + Array(equivalentClass_cache[self])).uniq
|
46
|
+
terms.each {|t| yield t} if block_given?
|
47
|
+
terms
|
48
|
+
when RDF::Statement
|
49
|
+
statements = []
|
50
|
+
if self.predicate == RDF.type
|
51
|
+
if term = (RDF::Vocabulary.find_term(self.object) rescue nil)
|
52
|
+
term._entail_equivalentClass do |t|
|
53
|
+
statements << RDF::Statement.new(self.to_hash.merge(object: t))
|
54
|
+
end
|
277
55
|
end
|
278
|
-
|
279
|
-
restrictions.freeze
|
280
56
|
end
|
57
|
+
statements.each {|s| yield s} if block_given?
|
58
|
+
statements
|
59
|
+
else []
|
281
60
|
end
|
61
|
+
end
|
282
62
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
63
|
+
##
|
64
|
+
# For a Term: yield or return return inferred equivalentProperty relationships
|
65
|
+
# For a Statement: yield or return inferred statements having a equivalentProperty relationship to predicate of this statement
|
66
|
+
# @private
|
67
|
+
def _entail_equivalentProperty
|
68
|
+
case self
|
69
|
+
when RDF::Vocabulary::Term
|
70
|
+
unless property? && respond_to?(:equivalentProperty)
|
71
|
+
yield self if block_given?
|
72
|
+
return Array(self)
|
73
|
+
end
|
289
74
|
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
75
|
+
# Initialize equivalentProperty_cache by iterating over all defined property terms having an `owl:equivalentProperty` attribute and adding the source class as an equivalent of the destination class
|
76
|
+
if equivalentProperty_cache.empty?
|
77
|
+
RDF::Vocabulary.each do |v|
|
78
|
+
v.each do |term|
|
79
|
+
term.equivalentProperty.each do |equiv|
|
80
|
+
(equivalentProperty_cache[equiv] ||= []) << term
|
81
|
+
end if term.property?
|
82
|
+
end
|
294
83
|
end
|
295
|
-
|
296
|
-
(props + direct_props).sort.freeze
|
297
84
|
end
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
case classes.first
|
307
|
-
when '|' # Union of classes
|
308
|
-
cls = yield(classes[1]).dup
|
309
|
-
classes[2..-1].each {|cls2| cls = cls | yield(cls2)}
|
310
|
-
cls
|
311
|
-
when '&' # Intersection of classes
|
312
|
-
cls = yield(classes[1]).dup
|
313
|
-
classes[2..-1].each {|cls2| cls = cls & yield(cls2)}
|
314
|
-
cls
|
315
|
-
else
|
316
|
-
$logger.error "Unexpected operator in S-Exp for #{@resource}: #{classes.inspect}" unless classes.empty?
|
317
|
-
classes.dup
|
85
|
+
terms = (self.equivalentProperty + Array(equivalentProperty_cache[self])).uniq
|
86
|
+
terms.each {|t| yield t} if block_given?
|
87
|
+
terms
|
88
|
+
when RDF::Statement
|
89
|
+
statements = []
|
90
|
+
if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
|
91
|
+
term._entail_equivalentProperty do |t|
|
92
|
+
statements << RDF::Statement.new(self.to_hash.merge(predicate: t))
|
318
93
|
end
|
319
|
-
else
|
320
|
-
$logger.error "Unexpected value in S-Exp for #{@resource}: #{classes.inspect}" if classes
|
321
|
-
nil
|
322
94
|
end
|
95
|
+
statements.each {|s| yield s} if block_given?
|
96
|
+
statements
|
97
|
+
else []
|
323
98
|
end
|
324
99
|
end
|
325
100
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
101
|
+
##
|
102
|
+
# EquivalentClass of this term, also populates reverse equivalents.
|
103
|
+
#
|
104
|
+
# When first called, this initializes a cache of reverse terms to terms where the the reverse term is listed as an equivalent of the original term.
|
105
|
+
#
|
106
|
+
# It returns the list of terms which are equivalent to this term however defined.
|
107
|
+
# @return [Array<RDF::Vocabulary::Term>]
|
108
|
+
def equivalentClass
|
109
|
+
raise RDF::Reasoner::Error, "#{self} Can't entail equivalentClass" unless class?
|
110
|
+
Array(self.attributes["owl:equivalentClass"]).map {|t| RDF::Vocabulary.expand_pname(t)}
|
111
|
+
end
|
334
112
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
113
|
+
##
|
114
|
+
# EquivalentProperty of this term, also populates reverse equivalents.
|
115
|
+
#
|
116
|
+
# When first called, this initializes a cache of reverse terms to terms where the the reverse term is listed as an equivalent of the original term.
|
117
|
+
#
|
118
|
+
# It returns the list of terms which are equivalent to this term however defined.
|
119
|
+
# @return [Array<RDF::Vocabulary::Term>]
|
120
|
+
def equivalentProperty
|
121
|
+
raise RDF::Reasoner::Error, "#{self} Can't entail equivalentProperty" unless property?
|
122
|
+
Array(self.attributes["owl:equivalentProperty"]).map {|t| RDF::Vocabulary.expand_pname(t)}
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.included(mod)
|
126
|
+
mod.add_entailment :equivalentClass, :_entail_equivalentClass
|
127
|
+
mod.add_entailment :equivalentProperty, :_entail_equivalentProperty
|
345
128
|
end
|
346
129
|
end
|
130
|
+
|
131
|
+
# Extend Term with these methods
|
132
|
+
::RDF::Vocabulary::Term.send(:include, OWL)
|
133
|
+
|
134
|
+
# Extend Statement with these methods
|
135
|
+
::RDF::Statement.send(:include, OWL)
|
136
|
+
|
137
|
+
# Extend Enumerable with these methods
|
138
|
+
::RDF::Enumerable.send(:include, OWL)
|
139
|
+
|
140
|
+
# Extend Mutable with these methods
|
141
|
+
::RDF::Mutable.send(:include, OWL)
|
347
142
|
end
|
data/lib/rdf/reasoner/rdfs.rb
CHANGED
@@ -4,7 +4,7 @@ module RDF::Reasoner
|
|
4
4
|
##
|
5
5
|
# Rules for generating RDFS entailment triples
|
6
6
|
#
|
7
|
-
# Extends `RDF::Vocabulary::Term` with specific entailment capabilities
|
7
|
+
# Extends `RDF::Vocabulary::Term` and `RDF::Statement` with specific entailment capabilities
|
8
8
|
module RDFS
|
9
9
|
##
|
10
10
|
# @return [RDF::Util::Cache]
|
@@ -35,22 +35,59 @@ module RDF::Reasoner
|
|
35
35
|
end
|
36
36
|
|
37
37
|
##
|
38
|
-
#
|
38
|
+
# For a Term: yield or return inferred subClassOf relationships by recursively applying to named super classes to get a complete set of classes in the ancestor chain of this class
|
39
|
+
# For a Statement: if predicate is `rdf:types`, yield or return inferred statements having a subClassOf relationship to the type of this statement
|
39
40
|
# @private
|
40
41
|
def _entail_subClassOf
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
case self
|
43
|
+
when RDF::Vocabulary::Term
|
44
|
+
unless class? && respond_to?(:subClassOf)
|
45
|
+
yield self if block_given?
|
46
|
+
return Array(self)
|
47
|
+
end
|
48
|
+
terms = subClassOf_cache[self] ||= (
|
49
|
+
Array(self.subClassOf).
|
50
|
+
map {|c| c._entail_subClassOf rescue c}.
|
51
|
+
flatten +
|
52
|
+
Array(self)
|
53
|
+
).compact
|
54
|
+
terms.each {|t| yield t} if block_given?
|
55
|
+
terms
|
56
|
+
when RDF::Statement
|
57
|
+
statements = []
|
58
|
+
if self.predicate == RDF.type
|
59
|
+
if term = (RDF::Vocabulary.find_term(self.object) rescue nil)
|
60
|
+
term._entail_subClassOf do |t|
|
61
|
+
statements << RDF::Statement.new(self.to_hash.merge(object: t))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
statements.each {|s| yield s} if block_given?
|
66
|
+
statements
|
67
|
+
else []
|
44
68
|
end
|
45
69
|
end
|
46
70
|
|
47
71
|
##
|
48
|
-
#
|
72
|
+
# For a Term: yield or return inferred subClass relationships by recursively applying to named sub classes to get a complete set of classes in the descendant chain of this class
|
73
|
+
# For a Statement: this is a no-op, as it's not useful in this context
|
49
74
|
# @private
|
50
75
|
def _entail_subClass
|
51
|
-
|
52
|
-
|
53
|
-
|
76
|
+
case self
|
77
|
+
when RDF::Vocabulary::Term
|
78
|
+
unless class?
|
79
|
+
yield self if block_given?
|
80
|
+
return Array(self)
|
81
|
+
end
|
82
|
+
terms = descendant_cache[self] ||= (
|
83
|
+
Array(self.subClass).
|
84
|
+
map {|c| c._entail_subClass rescue c}.
|
85
|
+
flatten +
|
86
|
+
Array(self)
|
87
|
+
).compact
|
88
|
+
terms.each {|t| yield t} if block_given?
|
89
|
+
terms
|
90
|
+
else []
|
54
91
|
end
|
55
92
|
end
|
56
93
|
|
@@ -58,7 +95,6 @@ module RDF::Reasoner
|
|
58
95
|
# Get the immediate subclasses of this class.
|
59
96
|
#
|
60
97
|
# This iterates over terms defined in the vocabulary of this term, as well as the vocabularies imported by this vocabulary.
|
61
|
-
|
62
98
|
# @return [Array<RDF::Vocabulary::Term>]
|
63
99
|
def subClass
|
64
100
|
raise RDF::Reasoner::Error, "#{self} Can't entail subClass" unless class?
|
@@ -68,12 +104,70 @@ module RDF::Reasoner
|
|
68
104
|
end
|
69
105
|
|
70
106
|
##
|
71
|
-
#
|
107
|
+
# 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
|
108
|
+
# For a Statement: yield or return inferred statements having a subPropertyOf relationship to predicate of this statement
|
72
109
|
# @private
|
73
110
|
def _entail_subPropertyOf
|
74
|
-
|
75
|
-
|
76
|
-
|
111
|
+
case self
|
112
|
+
when RDF::Vocabulary::Term
|
113
|
+
unless property? && respond_to?(:subPropertyOf)
|
114
|
+
yield self if block_given?
|
115
|
+
return Array(self)
|
116
|
+
end
|
117
|
+
terms = subPropertyOf_cache[self] ||= (
|
118
|
+
Array(self.subPropertyOf).
|
119
|
+
map {|c| c._entail_subPropertyOf rescue c}.
|
120
|
+
flatten +
|
121
|
+
Array(self)
|
122
|
+
).compact
|
123
|
+
terms.each {|t| yield t} if block_given?
|
124
|
+
terms
|
125
|
+
when RDF::Statement
|
126
|
+
statements = []
|
127
|
+
if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
|
128
|
+
term._entail_subPropertyOf do |t|
|
129
|
+
statements << RDF::Statement.new(self.to_hash.merge(predicate: t))
|
130
|
+
end
|
131
|
+
end
|
132
|
+
statements.each {|s| yield s} if block_given?
|
133
|
+
statements
|
134
|
+
else []
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# For a Statement: yield or return inferred statements having an rdf:type of the domain of the statement predicate
|
140
|
+
# @private
|
141
|
+
def _entail_domain
|
142
|
+
case self
|
143
|
+
when RDF::Statement
|
144
|
+
statements = []
|
145
|
+
if term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
|
146
|
+
term.domain.each do |t|
|
147
|
+
statements << RDF::Statement.new(self.to_hash.merge(predicate: RDF.type, object: t))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
statements.each {|s| yield s} if block_given?
|
151
|
+
statements
|
152
|
+
else []
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# For a Statement: if object is a resource, yield or return inferred statements having an rdf:type of the range of the statement predicate
|
158
|
+
# @private
|
159
|
+
def _entail_range
|
160
|
+
case self
|
161
|
+
when RDF::Statement
|
162
|
+
statements = []
|
163
|
+
if object.resource? && term = (RDF::Vocabulary.find_term(self.predicate) rescue nil)
|
164
|
+
term.range.each do |t|
|
165
|
+
statements << RDF::Statement.new(self.to_hash.merge(subject: self.object, predicate: RDF.type, object: t))
|
166
|
+
end
|
167
|
+
end
|
168
|
+
statements.each {|s| yield s} if block_given?
|
169
|
+
statements
|
170
|
+
else []
|
77
171
|
end
|
78
172
|
end
|
79
173
|
|
@@ -95,7 +189,7 @@ module RDF::Reasoner
|
|
95
189
|
# Fully entailed types of the resource
|
96
190
|
types = options.fetch(:types) do
|
97
191
|
queryable.query(:subject => resource, :predicate => RDF.type).
|
98
|
-
map {|s| (t = RDF::Vocabulary.find_term(s.object)) && t.entail(:subClassOf)}.
|
192
|
+
map {|s| (t = (RDF::Vocabulary.find_term(s.object)) rescue nil) && t.entail(:subClassOf)}.
|
99
193
|
flatten.
|
100
194
|
uniq.
|
101
195
|
compact
|
@@ -138,7 +232,7 @@ module RDF::Reasoner
|
|
138
232
|
# Fully entailed types of the resource
|
139
233
|
types = options.fetch(:types) do
|
140
234
|
queryable.query(:subject => resource, :predicate => RDF.type).
|
141
|
-
map {|s| (t = RDF::Vocabulary.find_term(s.object)) && t.entail(:subClassOf)}.
|
235
|
+
map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
|
142
236
|
flatten.
|
143
237
|
uniq.
|
144
238
|
compact
|
@@ -161,9 +255,20 @@ module RDF::Reasoner
|
|
161
255
|
mod.add_entailment :subClassOf, :_entail_subClassOf
|
162
256
|
mod.add_entailment :subClass, :_entail_subClass
|
163
257
|
mod.add_entailment :subPropertyOf, :_entail_subPropertyOf
|
258
|
+
mod.add_entailment :domain, :_entail_domain
|
259
|
+
mod.add_entailment :range, :_entail_range
|
164
260
|
end
|
165
261
|
end
|
166
262
|
|
167
|
-
# Extend
|
263
|
+
# Extend Term with these methods
|
168
264
|
::RDF::Vocabulary::Term.send(:include, RDFS)
|
265
|
+
|
266
|
+
# Extend Statement with these methods
|
267
|
+
::RDF::Statement.send(:include, RDFS)
|
268
|
+
|
269
|
+
# Extend Enumerable with these methods
|
270
|
+
::RDF::Enumerable.send(:include, RDFS)
|
271
|
+
|
272
|
+
# Extend Mutable with these methods
|
273
|
+
::RDF::Mutable.send(:include, RDFS)
|
169
274
|
end
|
data/lib/rdf/reasoner/schema.rb
CHANGED
@@ -47,7 +47,7 @@ module RDF::Reasoner
|
|
47
47
|
# Fully entailed types of the resource
|
48
48
|
types = options.fetch(:types) do
|
49
49
|
queryable.query(:subject => resource, :predicate => RDF.type).
|
50
|
-
map {|s| (t = RDF::Vocabulary.find_term(s.object)) && t.entail(:subClassOf)}.
|
50
|
+
map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
|
51
51
|
flatten.
|
52
52
|
uniq.
|
53
53
|
compact
|
@@ -147,7 +147,7 @@ module RDF::Reasoner
|
|
147
147
|
# Fully entailed types of the resource
|
148
148
|
types = options.fetch(:types) do
|
149
149
|
queryable.query(:subject => resource, :predicate => RDF.type).
|
150
|
-
map {|s| (t = RDF::Vocabulary.find_term(s.object)) && t.entail(:subClassOf)}.
|
150
|
+
map {|s| (t = (RDF::Vocabulary.find_term(s.object) rescue nil)) && t.entail(:subClassOf)}.
|
151
151
|
flatten.
|
152
152
|
uniq.
|
153
153
|
compact
|
metadata
CHANGED
@@ -1,117 +1,132 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rdf-reasoner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Gregg Kellogg
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2014-
|
12
|
+
date: 2014-11-11 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: rdf
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- -
|
19
|
+
- - ~>
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '1.1'
|
20
|
-
- -
|
22
|
+
- - ! '>='
|
21
23
|
- !ruby/object:Gem::Version
|
22
24
|
version: 1.1.4.2
|
23
25
|
type: :runtime
|
24
26
|
prerelease: false
|
25
27
|
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
26
29
|
requirements:
|
27
|
-
- -
|
30
|
+
- - ~>
|
28
31
|
- !ruby/object:Gem::Version
|
29
32
|
version: '1.1'
|
30
|
-
- -
|
33
|
+
- - ! '>='
|
31
34
|
- !ruby/object:Gem::Version
|
32
35
|
version: 1.1.4.2
|
33
36
|
- !ruby/object:Gem::Dependency
|
34
37
|
name: rdf-xsd
|
35
38
|
requirement: !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
36
40
|
requirements:
|
37
|
-
- -
|
41
|
+
- - ~>
|
38
42
|
- !ruby/object:Gem::Version
|
39
43
|
version: '1.1'
|
40
44
|
type: :runtime
|
41
45
|
prerelease: false
|
42
46
|
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
43
48
|
requirements:
|
44
|
-
- -
|
49
|
+
- - ~>
|
45
50
|
- !ruby/object:Gem::Version
|
46
51
|
version: '1.1'
|
47
52
|
- !ruby/object:Gem::Dependency
|
48
53
|
name: rdf-turtle
|
49
54
|
requirement: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
50
56
|
requirements:
|
51
|
-
- -
|
57
|
+
- - ~>
|
52
58
|
- !ruby/object:Gem::Version
|
53
59
|
version: '1.1'
|
54
60
|
type: :runtime
|
55
61
|
prerelease: false
|
56
62
|
version_requirements: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
57
64
|
requirements:
|
58
|
-
- -
|
65
|
+
- - ~>
|
59
66
|
- !ruby/object:Gem::Version
|
60
67
|
version: '1.1'
|
61
68
|
- !ruby/object:Gem::Dependency
|
62
69
|
name: linkeddata
|
63
70
|
requirement: !ruby/object:Gem::Requirement
|
71
|
+
none: false
|
64
72
|
requirements:
|
65
|
-
- -
|
73
|
+
- - ~>
|
66
74
|
- !ruby/object:Gem::Version
|
67
75
|
version: '1.1'
|
68
76
|
type: :development
|
69
77
|
prerelease: false
|
70
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
71
80
|
requirements:
|
72
|
-
- -
|
81
|
+
- - ~>
|
73
82
|
- !ruby/object:Gem::Version
|
74
83
|
version: '1.1'
|
75
84
|
- !ruby/object:Gem::Dependency
|
76
85
|
name: equivalent-xml
|
77
86
|
requirement: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
78
88
|
requirements:
|
79
|
-
- -
|
89
|
+
- - ~>
|
80
90
|
- !ruby/object:Gem::Version
|
81
91
|
version: '0.4'
|
82
92
|
type: :development
|
83
93
|
prerelease: false
|
84
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
85
96
|
requirements:
|
86
|
-
- -
|
97
|
+
- - ~>
|
87
98
|
- !ruby/object:Gem::Version
|
88
99
|
version: '0.4'
|
89
100
|
- !ruby/object:Gem::Dependency
|
90
101
|
name: rspec
|
91
102
|
requirement: !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
92
104
|
requirements:
|
93
|
-
- -
|
105
|
+
- - ~>
|
94
106
|
- !ruby/object:Gem::Version
|
95
107
|
version: '3.0'
|
96
108
|
type: :development
|
97
109
|
prerelease: false
|
98
110
|
version_requirements: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
99
112
|
requirements:
|
100
|
-
- -
|
113
|
+
- - ~>
|
101
114
|
- !ruby/object:Gem::Version
|
102
115
|
version: '3.0'
|
103
116
|
- !ruby/object:Gem::Dependency
|
104
117
|
name: yard
|
105
118
|
requirement: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
106
120
|
requirements:
|
107
|
-
- -
|
121
|
+
- - ~>
|
108
122
|
- !ruby/object:Gem::Version
|
109
123
|
version: '0.8'
|
110
124
|
type: :development
|
111
125
|
prerelease: false
|
112
126
|
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
113
128
|
requirements:
|
114
|
-
- -
|
129
|
+
- - ~>
|
115
130
|
- !ruby/object:Gem::Version
|
116
131
|
version: '0.8'
|
117
132
|
description: Reasons over RDFS/OWL vocabularies to generate statements which are entailed
|
@@ -127,35 +142,36 @@ files:
|
|
127
142
|
- README.md
|
128
143
|
- UNLICENSE
|
129
144
|
- VERSION
|
130
|
-
- lib/rdf/reasoner.rb
|
131
145
|
- lib/rdf/reasoner/extensions.rb
|
132
146
|
- lib/rdf/reasoner/owl.rb
|
133
147
|
- lib/rdf/reasoner/rdfs.rb
|
134
148
|
- lib/rdf/reasoner/schema.rb
|
135
149
|
- lib/rdf/reasoner/version.rb
|
150
|
+
- lib/rdf/reasoner.rb
|
136
151
|
homepage: http://github.com/gkellogg/rdf-reasoner
|
137
152
|
licenses:
|
138
153
|
- Public Domain
|
139
|
-
metadata: {}
|
140
154
|
post_install_message:
|
141
155
|
rdoc_options: []
|
142
156
|
require_paths:
|
143
157
|
- lib
|
144
158
|
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
none: false
|
145
160
|
requirements:
|
146
|
-
- -
|
161
|
+
- - ! '>='
|
147
162
|
- !ruby/object:Gem::Version
|
148
163
|
version: 1.9.3
|
149
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
|
+
none: false
|
150
166
|
requirements:
|
151
|
-
- -
|
167
|
+
- - ! '>='
|
152
168
|
- !ruby/object:Gem::Version
|
153
169
|
version: '0'
|
154
170
|
requirements: []
|
155
171
|
rubyforge_project:
|
156
|
-
rubygems_version:
|
172
|
+
rubygems_version: 1.8.23.2
|
157
173
|
signing_key:
|
158
|
-
specification_version:
|
174
|
+
specification_version: 3
|
159
175
|
summary: RDFS/OWL Reasoner for RDF.rb
|
160
176
|
test_files: []
|
161
177
|
has_rdoc: false
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: f6a98adc5516082d31f711b399c152f140a02bb5
|
4
|
-
data.tar.gz: 39fa2fc036816834e1bdf676ed4d7ad0898cce28
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 729ae98dd83b486197f0eb73d9465116dd40aa16d385b05c94c1228fa6ed0f882aeb85f84b0b492a0c1ba5931d231147cc36cce2a9c2c166d5af547971324ea3
|
7
|
-
data.tar.gz: 3c0a07eefe32d2e5e4afd983546e667028c48c050fde90cbd67ddaf9ea46ad6bc64ef143ea73db2078840eafbb27b4bd7ca5b6f7ff566ad5852705e605f71e79
|