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.
@@ -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