pomegranate 0.9
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.markdown +77 -0
- data/Rakefile +22 -0
- data/coverage/index.html +279 -0
- data/coverage/lib-pomegranate-rdfs_plus_rulebook_rb.html +951 -0
- data/coverage/lib-pomegranate_rb.html +639 -0
- data/lib/pomegranate.rb +29 -0
- data/lib/pomegranate/rdfs_plus_rulebook.rb +327 -0
- data/lib/pomegranate/rdfs_rulebook.rb +188 -0
- data/pomegranate.gemspec +16 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/owl_equivalent_class_spec.rb +42 -0
- data/spec/unit/owl_equivalent_property_spec.rb +45 -0
- data/spec/unit/owl_functional_property_spec.rb +42 -0
- data/spec/unit/owl_inverse_functional_property_spec.rb +41 -0
- data/spec/unit/owl_inverse_of_spec.rb +45 -0
- data/spec/unit/owl_same_as_spec.rb +51 -0
- data/spec/unit/owl_symmetric_property_spec.rb +42 -0
- data/spec/unit/owl_transitive_property_spec.rb +47 -0
- data/spec/unit/rdfs_domain_spec.rb +43 -0
- data/spec/unit/rdfs_range_spec.rb +45 -0
- data/spec/unit/rdfs_subclass_of_spec.rb +45 -0
- data/spec/unit/rdfs_subproperty_of_spec.rb +46 -0
- metadata +85 -0
data/lib/pomegranate.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# This file is part of Pomegranate
|
2
|
+
#
|
3
|
+
# Pomegranate is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU Lesser General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# Pomegranate is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU Lesser General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Lesser General Public License
|
14
|
+
# along with Pomegranate. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'pathname'
|
19
|
+
require 'ruleby'
|
20
|
+
include Ruleby
|
21
|
+
|
22
|
+
class Pathname
|
23
|
+
def /(path)
|
24
|
+
(self + path).expand_path
|
25
|
+
end
|
26
|
+
end # class Pathname
|
27
|
+
|
28
|
+
dir = Pathname(__FILE__).dirname.expand_path / 'pomegranate'
|
29
|
+
require dir / 'rdfs_plus_rulebook'
|
@@ -0,0 +1,327 @@
|
|
1
|
+
# This file is part of the Pomegranate project (http://pius.github.com/pomegranate/)
|
2
|
+
#
|
3
|
+
# This application is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the Ruby license defined in the
|
5
|
+
# LICENSE.txt file.
|
6
|
+
#
|
7
|
+
# Copyright (c) 2008 Pius Uzamere. All rights reserved.
|
8
|
+
#
|
9
|
+
# * Authors: Pius Uzamere
|
10
|
+
#
|
11
|
+
|
12
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '../lib/')
|
13
|
+
require 'lib/pomegranate/rdfs_rulebook'
|
14
|
+
|
15
|
+
class RdfsPlusRulebook < RdfsRulebook
|
16
|
+
|
17
|
+
def rules
|
18
|
+
rdfs_rules
|
19
|
+
rdfs_plus_rules
|
20
|
+
end
|
21
|
+
|
22
|
+
#nodoc
|
23
|
+
def rdfs_plus_rules
|
24
|
+
##
|
25
|
+
# Implements Type Propagation through owl:inverseOf
|
26
|
+
#
|
27
|
+
# ==== Semantics
|
28
|
+
# Given:
|
29
|
+
# P owl:inverseOf Q
|
30
|
+
# x P y
|
31
|
+
#
|
32
|
+
# Infer:
|
33
|
+
# y Q x
|
34
|
+
#
|
35
|
+
# ==== Example
|
36
|
+
# p = Triple.new(":Pius", ":took_a_class_taught_by", ":Winston");
|
37
|
+
# h = Triple.new(":took_a_class_taught_by", "owl:inverseOf", ":taught")
|
38
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Winston", "taught", ":Pius")
|
39
|
+
#
|
40
|
+
# @author Pius Uzamere
|
41
|
+
def owl_inverse_of
|
42
|
+
end
|
43
|
+
|
44
|
+
rule :owl_inverse_of,
|
45
|
+
[Triple,:fact,{m.predicate=>:pred, m.object => :new_subj, m.subject => :new_obj}],
|
46
|
+
[Triple,:ont_statement,{m.object => :inferred_pred},m.predicate=="owl:inverseOf", m.subject == b(:pred)],
|
47
|
+
[:not, Triple, m.predicate==b(:inferred_pred), m.subject==b(:new_subj), m.object==b(:new_obj)] do |v|
|
48
|
+
inferred_property = v[:ont_statement].object
|
49
|
+
obj = v[:fact].subject
|
50
|
+
subj = v[:fact].object
|
51
|
+
assert Triple.new(subj, inferred_property, obj)
|
52
|
+
puts "Made type inference based on owl:inverseOf: Triple(#{subj}, #{inferred_property}, #{obj})"
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Implements Type Propagation through owl:SymmetricProperty
|
57
|
+
#
|
58
|
+
# ==== Semantics
|
59
|
+
# Given:
|
60
|
+
# P rdf:type owl:SymmetricProperty
|
61
|
+
#
|
62
|
+
# Infer:
|
63
|
+
# P owl:inverseOf P
|
64
|
+
#
|
65
|
+
# ==== Example
|
66
|
+
# p = Triple.new(":Pius", ":was_in_a_class_with", ":Adam");
|
67
|
+
# h = Triple.new(":was_in_a_class_with", "rdf:type", "owl:SymmetricProperty")
|
68
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Adam", ":was_in_a_class_with", ":Pius")
|
69
|
+
#
|
70
|
+
# @author Pius Uzamere
|
71
|
+
def owl_symmetric_property
|
72
|
+
end
|
73
|
+
|
74
|
+
rule :owl_symmetric_property,
|
75
|
+
[Triple,:ont_statement,m.predicate=="rdf:type",m.object=="owl:SymmetricProperty"] do |v|
|
76
|
+
prop = v[:ont_statement].subject
|
77
|
+
assert Triple.new(prop, "owl:inverseOf", prop)
|
78
|
+
puts "Made type inference based on owl:SymmetricProperty: Triple(#{prop}, owl:inverseOf, #{prop})"
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# Implements Type Propagation through owl:TransitiveProperty
|
83
|
+
#
|
84
|
+
# ==== Semantics
|
85
|
+
# Given:
|
86
|
+
# P rdf:type owl:TransitiveProperty
|
87
|
+
# X P Y
|
88
|
+
# X P Z
|
89
|
+
#
|
90
|
+
# Infer:
|
91
|
+
# X P Z
|
92
|
+
#
|
93
|
+
# ==== Example
|
94
|
+
# p = Triple.new(":Dirichlet", ":is_an_academic_ancestor_of", ":Minsky");
|
95
|
+
# h = Triple.new(":Poisson", ":is_an_academic_ancestor_of", ":Dirichlet");
|
96
|
+
# j = Triple.new(":is_an_academic_ancestor_of", "rdf:type", "owl:TransitiveProperty");
|
97
|
+
# assert p; assert h; assert j; #=> infers a triple ~= Triple.new(":Poisson", ":is_an_academic_ancestor_of", ":Minsky")
|
98
|
+
#
|
99
|
+
# @author Pius Uzamere
|
100
|
+
def owl_transitive_property
|
101
|
+
end
|
102
|
+
|
103
|
+
rule :owl_transitive_property,
|
104
|
+
[Triple,:ont_statement,{m.subject => :trans_prop},m.predicate=="rdf:type",m.object=="owl:TransitiveProperty"],
|
105
|
+
[Triple,:fact1,{m.predicate=>:predi, m.subject => :sub, m.object => :trans_obj}, m.predicate == b(:trans_prop), m.subject.not== m.object],
|
106
|
+
[Triple,:fact2, m.predicate==b(:predi), m.subject==b(:trans_obj), m.predicate.not=="owl:inverseOf", m.object.not== b(:sub) ] do |v|
|
107
|
+
subj = v[:fact1].subject
|
108
|
+
obj = v[:fact2].object
|
109
|
+
prop = v[:ont_statement].subject
|
110
|
+
assert Triple.new(subj, prop, obj)
|
111
|
+
puts "Made type inference based on owl:TransitiveProperty: Triple(#{subj}, #{prop}, #{obj})"
|
112
|
+
end
|
113
|
+
|
114
|
+
##
|
115
|
+
# Implements Class Equivalence through owl:equivalentClass
|
116
|
+
#
|
117
|
+
# ==== Semantics
|
118
|
+
# Given:
|
119
|
+
# A owl:equivalentClass B
|
120
|
+
# r rdf:type A
|
121
|
+
#
|
122
|
+
# Infer:
|
123
|
+
# r rdf:type B
|
124
|
+
#
|
125
|
+
# AND
|
126
|
+
#
|
127
|
+
# Given:
|
128
|
+
# C owl:equivalentClass D
|
129
|
+
# C rdfs:subClassOf D
|
130
|
+
# z rdf:type D
|
131
|
+
#
|
132
|
+
# Infer:
|
133
|
+
# z rdf:type C
|
134
|
+
#
|
135
|
+
# ==== Example
|
136
|
+
# p = Triple.new("mit:class", "owl:equivalentClass", "mit:subject");
|
137
|
+
# h = Triple.new(":6.111", "rdf:type", "mit:class");
|
138
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":6.111", ":rdf:type", ":mit:subject")
|
139
|
+
#
|
140
|
+
# @author Pius Uzamere
|
141
|
+
def owl_equivalent_class
|
142
|
+
end
|
143
|
+
|
144
|
+
rule :owl_equivalent_class,
|
145
|
+
[Triple,:ont_statement,m.predicate=="owl:equivalentClass"] do |v|
|
146
|
+
assert Triple.new("owl:equivalentClass", "rdf:type", "owl:SymmetricProperty")
|
147
|
+
assert Triple.new("owl:equivalentClass", "rdfs:subPropertyOf", "rdfs:subClassOf")
|
148
|
+
#this is cute . . . only annoying thing is that you don't get the downstream explanation of the inferences
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
##
|
153
|
+
# Implements Property Equivalence through owl:equivalentProperty
|
154
|
+
#
|
155
|
+
# ==== Semantics
|
156
|
+
# Given:
|
157
|
+
# A owl:equivalentProperty B
|
158
|
+
# r A c
|
159
|
+
#
|
160
|
+
# Infer:
|
161
|
+
# r B C
|
162
|
+
#
|
163
|
+
# AND
|
164
|
+
#
|
165
|
+
# Given:
|
166
|
+
# C owl:equivalentClass D
|
167
|
+
# C rdfs:subClassOf D
|
168
|
+
# z rdf:type D
|
169
|
+
#
|
170
|
+
# Infer:
|
171
|
+
# z rdf:type C
|
172
|
+
#
|
173
|
+
# ==== Example
|
174
|
+
# p = Triple.new("mit:took_class", "owl:equivalentProperty", "mit:took_course");
|
175
|
+
# h = Triple.new(":Pius", "mit:took_course", ":6.111");
|
176
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Pius", "mit:took_class", ":6.111")
|
177
|
+
#
|
178
|
+
# @author Pius Uzamere
|
179
|
+
|
180
|
+
def owl_equivalent_property
|
181
|
+
end
|
182
|
+
|
183
|
+
rule :owl_equivalent_property,
|
184
|
+
[Triple,:ont_statement,m.predicate=="owl:equivalentProperty"] do |v|
|
185
|
+
assert Triple.new("owl:equivalentProperty", "rdf:type", "owl:SymmetricProperty")
|
186
|
+
assert Triple.new("owl:equivalentProperty", "rdfs:subPropertyOf", "rdfs:subPropertyOf")
|
187
|
+
#this is cute . . . only annoying thing is that you don't get the downstream explanation of the inferences
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# Implements Individual Equivalence through owl:sameAs
|
192
|
+
#
|
193
|
+
# ==== Semantics
|
194
|
+
# Given:
|
195
|
+
# x owl:sameAs y
|
196
|
+
# o P x
|
197
|
+
#
|
198
|
+
# Infer:
|
199
|
+
# o P y
|
200
|
+
#
|
201
|
+
# AND
|
202
|
+
#
|
203
|
+
# Given:
|
204
|
+
# x owl:sameAs y
|
205
|
+
# x P o
|
206
|
+
#
|
207
|
+
# Infer:
|
208
|
+
# z rdf:type C
|
209
|
+
#
|
210
|
+
# ==== Example
|
211
|
+
# p = Triple.new(":Pius", "owl:sameAs", ":Uzamere");
|
212
|
+
# h = Triple.new(":Pius", "mit:took_course", ":6.171");
|
213
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Uzamere", "mit:took_course", ":6.171")
|
214
|
+
#
|
215
|
+
# @author Pius Uzamere
|
216
|
+
|
217
|
+
def owl_same_as
|
218
|
+
end
|
219
|
+
|
220
|
+
rule :owl_same_as_symmetricity,
|
221
|
+
[Triple,:ont_statement, m.predicate=="owl:sameAs"] do |v|
|
222
|
+
assert Triple.new("owl:sameAs", "rdf:type", "owl:SymmetricProperty")
|
223
|
+
puts "asserting the symmetricity of owl:sameAs"
|
224
|
+
end
|
225
|
+
|
226
|
+
|
227
|
+
rule :owl_same_as_when_subject,
|
228
|
+
|
229
|
+
[Triple,:ont_statement,{m.subject => :original, m.object => :doppelganger}, m.predicate=="owl:sameAs"],
|
230
|
+
[Triple,:fact, {m.predicate => :p, m.object => :common_object}, m.subject == b(:original), m.subject.not== b(:doppelganger), m.predicate.not== "owl:sameAs"],
|
231
|
+
[:not, Triple, m.predicate==b(:p), m.subject==b(:doppelganger), m.object==b(:common_object)] do |v|
|
232
|
+
|
233
|
+
subj = v[:ont_statement].object
|
234
|
+
pred = v[:fact].predicate
|
235
|
+
obj = v[:fact].object
|
236
|
+
|
237
|
+
puts "Made type inference based on owl:sameAs: Triple(#{subj}, #{pred}, #{obj})"
|
238
|
+
assert Triple.new(subj, pred, obj)
|
239
|
+
#this is cute . . . only annoying thing is that you don't get the downstream explanation of the inferences
|
240
|
+
end
|
241
|
+
|
242
|
+
rule :owl_same_as_when_object,
|
243
|
+
[Triple,:ont_statement,{m.object => :original, m.subject => :doppelganger}, m.predicate=="owl:sameAs"],
|
244
|
+
[Triple,:fact, {m.predicate => :p, m.object => :ob, m.subject => :common_subject}, m.object == b(:original), m.object.not== b(:doppelganger), m.predicate.not== "owl:sameAs"],
|
245
|
+
[:not, Triple, m.predicate==b(:p), m.subject==b(:common_subject), m.object==b(:doppelganger)] do |v|
|
246
|
+
|
247
|
+
obj = v[:ont_statement].subject
|
248
|
+
pred = v[:fact].predicate
|
249
|
+
subj = v[:fact].subject
|
250
|
+
|
251
|
+
puts "Made type inference based on owl:sameAs: Triple(#{subj}, #{pred}, #{obj})"
|
252
|
+
assert Triple.new(subj, pred, obj)
|
253
|
+
#this is cute . . . only annoying thing is that you don't get the downstream explanation of the inferences
|
254
|
+
end
|
255
|
+
|
256
|
+
##
|
257
|
+
# owl:FunctionalProperty
|
258
|
+
#
|
259
|
+
# ==== Semantics
|
260
|
+
# Given:
|
261
|
+
# P rdf:type owl:FunctionalProperty
|
262
|
+
# x P y
|
263
|
+
# x P z
|
264
|
+
#
|
265
|
+
# Infer:
|
266
|
+
# y owl:sameAs z
|
267
|
+
#
|
268
|
+
# ==== Example
|
269
|
+
# p = Triple.new("mit:had_academic_advisor", "rdf:type", "owl:FunctionalProperty");
|
270
|
+
# h = Triple.new(":Pius", "mit:had_academic_advisor", ":Hal");
|
271
|
+
# d = Triple.new(":Pius", "mit:had_academic_advisor", ":Dude_Who_Wrote_SICP_With_Gerald_Sussman");
|
272
|
+
# assert p; assert h; assert d; #=> infers a triple ~= Triple.new(":Hal", "owl:sameAs", ":Dude_Who_Wrote_SICP_With_Gerald_Sussman")
|
273
|
+
#
|
274
|
+
# @author Pius Uzamere
|
275
|
+
|
276
|
+
def owl_functional_property
|
277
|
+
end
|
278
|
+
|
279
|
+
rule :owl_functional_property,
|
280
|
+
[Triple,:ont_statement,{m.subject => :the_prop}, m.predicate == "rdf:type", m.object=="owl:FunctionalProperty"],
|
281
|
+
[Triple,:fact1, {m.subject => :common_subject, m.object => :first_object}, m.predicate == b(:the_prop)],
|
282
|
+
[Triple,:fact2, {m.object => :second_object}, m.subject == b(:common_subject), m.predicate == b(:the_prop)] do |v|
|
283
|
+
|
284
|
+
subj = v[:fact1].object
|
285
|
+
obj = v[:fact2].object
|
286
|
+
|
287
|
+
puts "Made type inference based on owl:FunctionalProperty: Triple(#{subj}, owl:sameAs, #{obj})"
|
288
|
+
assert Triple.new(subj, "owl:sameAs", obj)
|
289
|
+
end
|
290
|
+
|
291
|
+
##
|
292
|
+
# owl:InverseFunctionalProperty
|
293
|
+
#
|
294
|
+
# ==== Semantics
|
295
|
+
# Given:
|
296
|
+
# P rdf:type owl:InverseFunctionalProperty
|
297
|
+
# z P x
|
298
|
+
# y P x
|
299
|
+
#
|
300
|
+
# Infer:
|
301
|
+
# y owl:sameAs z
|
302
|
+
#
|
303
|
+
# ==== Example
|
304
|
+
# p = Triple.new("mit:lived_alone_fall_2004_in", "rdf:type", "owl:FunctionalProperty");
|
305
|
+
# h = Triple.new(":Pius", "mit:lived_alone_fall_2004_in", ":pomegranate_314_at_Next_House");
|
306
|
+
# d = Triple.new(":2004_UA_President", "mit:lived_alone_fall_2004_in", ":pomegranate_314_at_Next_House");
|
307
|
+
# assert p; assert h; assert d; #=> infers a triple ~= Triple.new(":Pius", "owl:sameAs", ":2004_UA_President")
|
308
|
+
#
|
309
|
+
# @author Pius Uzamere
|
310
|
+
|
311
|
+
def owl_inverse_functional_property
|
312
|
+
end
|
313
|
+
|
314
|
+
rule :owl_inverse_functional_property,
|
315
|
+
[Triple,:ont_statement,{m.subject => :the_prop}, m.predicate == "rdf:type", m.object=="owl:InverseFunctionalProperty"],
|
316
|
+
[Triple,:fact1, {m.object => :common_object, m.subject => :first_subject}, m.predicate == b(:the_prop)],
|
317
|
+
[Triple,:fact2, {m.subject => :second_subject}, m.object == b(:common_object), m.predicate == b(:the_prop)] do |v|
|
318
|
+
|
319
|
+
subj = v[:fact1].subject
|
320
|
+
obj = v[:fact2].subject
|
321
|
+
|
322
|
+
puts "Made type inference based on owl:InverseFunctionalProperty: Triple(#{subj}, owl:sameAs, #{obj})"
|
323
|
+
assert Triple.new(subj, "owl:sameAs", obj)
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# This file is part of the Pomegranate project (http://pius.github.com/pomegranate/)
|
2
|
+
#
|
3
|
+
# This application is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of the Ruby license defined in the
|
5
|
+
# LICENSE.txt file.
|
6
|
+
#
|
7
|
+
# Copyright (c) 2008 Pius Uzamere. All rights reserved.
|
8
|
+
#
|
9
|
+
# * Authors: Pius Uzamere
|
10
|
+
#
|
11
|
+
|
12
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '../lib/')
|
13
|
+
require 'rubygems'
|
14
|
+
require 'ruleby'
|
15
|
+
|
16
|
+
include Ruleby
|
17
|
+
|
18
|
+
class Triple
|
19
|
+
def initialize(subject,predicate,object)
|
20
|
+
@subject = subject
|
21
|
+
@predicate = predicate
|
22
|
+
@object= object
|
23
|
+
end
|
24
|
+
attr:subject, true
|
25
|
+
attr:predicate, true
|
26
|
+
attr:object, true
|
27
|
+
|
28
|
+
def ==(obj)
|
29
|
+
(@subject == obj.subject) && (@object == obj.object) && (@predicate == obj.predicate)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
class RdfsRulebook < Ruleby::Rulebook
|
36
|
+
|
37
|
+
def rules
|
38
|
+
rdfs_rules
|
39
|
+
end
|
40
|
+
|
41
|
+
#nodoc
|
42
|
+
def rdfs_rules
|
43
|
+
|
44
|
+
##
|
45
|
+
# Implements Type Propagation through rdfs:subClassOf
|
46
|
+
#
|
47
|
+
# ==== Semantics
|
48
|
+
# Given:
|
49
|
+
# A rdfs:subClassOf B
|
50
|
+
# r rdf:type A
|
51
|
+
#
|
52
|
+
# Infer:
|
53
|
+
# r rdf:type B
|
54
|
+
#
|
55
|
+
# ==== Example
|
56
|
+
# p = Triple.new(":Pius", "rdf:type", ":male");
|
57
|
+
# h = Triple.new(":male", "rdfs:subClassOf", ":human")
|
58
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Pius", "rdf:type", ":human")
|
59
|
+
#
|
60
|
+
# @author Pius Uzamere
|
61
|
+
def rdfs_sub_class_of
|
62
|
+
end
|
63
|
+
|
64
|
+
rule :rdfs_sub_class_of,
|
65
|
+
#TODO: add a patch to ruleby whereby the parser will raise when there's a no method error (e.g. m.subj)
|
66
|
+
[Triple,:fact,{m.subject => :subj, m.object=>:obj},m.predicate=="rdf:type"],
|
67
|
+
[Triple,:ont_statement,{m.object => :inferred_class },m.predicate=="rdfs:subClassOf", m.subject == b(:obj)],
|
68
|
+
[:not, Triple, m.predicate=="rdf:type", m.subject==b(:subj), m.object==b(:inferred_class)] do |v|
|
69
|
+
inferred_class = v[:ont_statement].object
|
70
|
+
subj = v[:fact].subject
|
71
|
+
assert Triple.new(subj, "rdf:type", inferred_class)
|
72
|
+
puts "Made type inference based on rdfs:subClassOf: Triple(#{subj}, rdf:type, #{inferred_class})"
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
##
|
77
|
+
# Implements Type Propagation through rdfs:subPropertyOf
|
78
|
+
#
|
79
|
+
# ==== Semantics
|
80
|
+
# Given:
|
81
|
+
# P rdfs:subPropertyOf R
|
82
|
+
# A P B
|
83
|
+
#
|
84
|
+
# Infer:
|
85
|
+
# A R B
|
86
|
+
#
|
87
|
+
# ==== Example
|
88
|
+
# p = Triple.new(":Pius", "mit:majored_in", ":Course_6");
|
89
|
+
# h = Triple.new("mit:majored_in", "rdfs:subPropertyOf", "mit:took_some_classes_in")
|
90
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Pius", "mit:took_some_classes_in", ":Course_6")
|
91
|
+
#
|
92
|
+
# @author Pius Uzamere
|
93
|
+
def rdfs_sub_property_of
|
94
|
+
end
|
95
|
+
|
96
|
+
rule :rdfs_sub_property_of,
|
97
|
+
[Triple,:fact,{m.predicate=>:pred, m.subject => :subj, m.object=>:obj}],
|
98
|
+
[Triple,:ont_statement, {m.object => :inferred_pred}, m.predicate=="rdfs:subPropertyOf", m.subject == b(:pred)],
|
99
|
+
[:not, Triple, m.predicate==b(:inferred_pred), m.subject==b(:subj), m.object==b(:obj)] do |v|
|
100
|
+
inferred_property = v[:ont_statement].object
|
101
|
+
subj = v[:fact].subject
|
102
|
+
obj = v[:fact].object
|
103
|
+
assert Triple.new(subj, inferred_property, obj)
|
104
|
+
puts "Made type inference based on subPropertyOf: Triple(#{subj},#{inferred_property}, #{obj})"
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Implements Type Propagation through rdfs:domain
|
109
|
+
#
|
110
|
+
# ==== Semantics
|
111
|
+
# Given:
|
112
|
+
# P rdfs:domain D
|
113
|
+
# x P y
|
114
|
+
#
|
115
|
+
# Infer:
|
116
|
+
# x rdf:type D
|
117
|
+
#
|
118
|
+
# ==== Example
|
119
|
+
# p = Triple.new("mit:majored_in", "rdfs:domain", ":student");
|
120
|
+
# h = Triple.new(":Pius", "mit:majored_in", ":Course_17")
|
121
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Pius", "rdf:type", ":student")
|
122
|
+
#
|
123
|
+
# @author Pius Uzamere
|
124
|
+
def rdfs_domain
|
125
|
+
end
|
126
|
+
|
127
|
+
rule :rdfs_domain,
|
128
|
+
[Triple,:fact,{m.predicate=>:pred}],
|
129
|
+
[Triple,:ont_statement,m.predicate=="rdfs:domain", m.subject == b(:pred)] do |v|
|
130
|
+
inferred_type = v[:ont_statement].object
|
131
|
+
subj = v[:fact].subject
|
132
|
+
assert Triple.new(subj, "rdf:type", inferred_type)
|
133
|
+
puts "Made type inference based on rdfs:domain: Triple(#{subj},rdf:type, #{inferred_type})"
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Implements Type Propagation through rdfs:range
|
138
|
+
#
|
139
|
+
# ==== Semantics
|
140
|
+
# Given:
|
141
|
+
# P rdfs:range R
|
142
|
+
# x P y
|
143
|
+
#
|
144
|
+
# Infer:
|
145
|
+
# y rdf:type R
|
146
|
+
#
|
147
|
+
# ==== Example
|
148
|
+
# p = Triple.new("mit:majored_in", "rdfs:range", ":major");
|
149
|
+
# h = Triple.new(":Pius", "mit:majored_in", ":Course_17")
|
150
|
+
# assert p; assert h; #=> infers a triple ~= Triple.new(":Pius", "rdf:type", ":student")
|
151
|
+
#
|
152
|
+
# @author Pius Uzamere
|
153
|
+
def rdfs_range
|
154
|
+
end
|
155
|
+
|
156
|
+
rule :rdfs_range,
|
157
|
+
[Triple,:fact,{m.predicate=>:pred}],
|
158
|
+
[Triple,:ont_statement,m.predicate=="rdfs:range", m.subject == b(:pred)] do |v|
|
159
|
+
inferred_type = v[:ont_statement].object
|
160
|
+
subj = v[:fact].object
|
161
|
+
assert Triple.new(subj, "rdf:type", inferred_type)
|
162
|
+
puts "Made type inference based on rdfs:range: Triple(#{subj},rdf:type, #{inferred_type})"
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
include Ruleby
|
169
|
+
engine :engine do |e|
|
170
|
+
#the engine takes an unreasonably long time to inspect -- consider patching Ruleby
|
171
|
+
RdfsRulebook.new(e).rdfs_rules
|
172
|
+
|
173
|
+
q = Triple.new(":Pius", "mit:majored_in", ":Course_6");
|
174
|
+
r = Triple.new("mit:majored_in", "rdfs:subPropertyOf", "mit:took_some_classes_in")
|
175
|
+
|
176
|
+
e.assert q
|
177
|
+
e.assert r
|
178
|
+
|
179
|
+
e.match
|
180
|
+
|
181
|
+
# p = Triple.new(":Pius", "rdf:type", ":male")
|
182
|
+
# h = Triple.new(":male", "rdfs:subClassOf", ":human")
|
183
|
+
# e.assert p
|
184
|
+
# e.assert h
|
185
|
+
# e.match
|
186
|
+
# puts "matching facts"
|
187
|
+
# puts e.facts
|
188
|
+
end
|