rdf-reasoner 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|