activerdf_rules 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +0 -0
- data/Manifest.txt +13 -0
- data/README.txt +33 -0
- data/Rakefile +49 -0
- data/examples/person_example.rb +67 -0
- data/lib/activerdf_rules/rule_base.rb +195 -0
- data/lib/activerdf_rules/rule_engine.rb +267 -0
- data/lib/activerdf_rules/rule_engine_mixin.rb +34 -0
- data/lib/activerdf_rules/version.rb +9 -0
- data/lib/activerdf_rules.rb +3 -0
- data/setup.rb +1585 -0
- data/test/activerdf_rules/owl_rulebase_test.rb +234 -0
- data/test/activerdf_rules/rdfs_rulebase_test.rb +95 -0
- data/test/activerdf_rules/rule_base_test.rb +103 -0
- data/test/activerdf_rules/rule_engine_mixin_test.rb +19 -0
- data/test/activerdf_rules/rule_engine_test.rb +59 -0
- data/test/activerdf_rules_test.rb +11 -0
- data/test/test_helper.rb +11 -0
- metadata +71 -0
@@ -0,0 +1,234 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
# TODO I need to finish this test case
|
4
|
+
# the problem I'm running into is that with rdflite I'm getting ambiguous
|
5
|
+
# column errors, but with redland I cannot find a way to query whether a triple
|
6
|
+
# exists. Currently doing an ask query on redland blows up in the
|
7
|
+
# FederationManager when called independently (because the FederationManager is
|
8
|
+
# expecting an array, but the query is returning a single boolean value) and
|
9
|
+
# when called on the adapter
|
10
|
+
class OWLRulebaseTest < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
ConnectionPool.clear
|
13
|
+
@adapter = ConnectionPool.add_data_source :type => :rdflite
|
14
|
+
@re = RuleEngine.new
|
15
|
+
@re.rule_base = RuleEngine::OWLRuleBase
|
16
|
+
@type = Namespace.lookup(:rdf, 'type')
|
17
|
+
@transProp = Namespace.lookup(:owl, 'TransitiveProperty')
|
18
|
+
@symProp = Namespace.lookup(:owl, 'SymmetricProperty')
|
19
|
+
@inverseOf = Namespace.lookup(:owl, 'inverseOf')
|
20
|
+
@disjointWith = Namespace.lookup(:owl, 'disjointWith')
|
21
|
+
@subClassOf = Namespace.lookup(:rdfs, 'subClassOf')
|
22
|
+
@sameAs = Namespace.lookup(:owl, 'sameAs')
|
23
|
+
@rdfclass = Namespace.lookup(:rdfs, 'Class')
|
24
|
+
@equivClass = Namespace.lookup(:owl, 'equivalentClass')
|
25
|
+
@complementOf = Namespace.lookup(:owl, 'complementOf')
|
26
|
+
@funcProp = Namespace.lookup(:owl, 'FunctionalProperty')
|
27
|
+
@invFuncProp = Namespace.lookup(:owl, 'InverseFunctionalProperty')
|
28
|
+
@onProperty = Namespace.lookup(:owl, 'onProperty')
|
29
|
+
@hasValue = Namespace.lookup(:owl, 'hasValue')
|
30
|
+
@allValuesFrom = Namespace.lookup(:owl, 'allValuesFrom')
|
31
|
+
@someValuesFrom = Namespace.lookup(:owl, 'someValuesFrom')
|
32
|
+
|
33
|
+
Namespace.register(:test, 'http://test.com/')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Enforcing transitivity of owl:TransitiveProperty.
|
37
|
+
def test_transitive_property
|
38
|
+
ancestor = Namespace.lookup(:test, 'ancestor')
|
39
|
+
sue = Namespace.lookup(:test, 'Sue')
|
40
|
+
mary = Namespace.lookup(:test, 'Mary')
|
41
|
+
anne = Namespace.lookup(:test, 'Anne')
|
42
|
+
@adapter.add ancestor, @type, @transProp
|
43
|
+
@adapter.add sue, ancestor, mary
|
44
|
+
@adapter.add mary, ancestor, anne
|
45
|
+
while @re.process_rules; end
|
46
|
+
|
47
|
+
assert sue.ancestor.include?(anne)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Semantics of owl:SymmetricProperty is enforced.
|
51
|
+
def test_symmetric_property
|
52
|
+
relative = Namespace.lookup(:test, 'relative')
|
53
|
+
sue = Namespace.lookup(:test, 'sue')
|
54
|
+
mary = Namespace.lookup(:test, 'mary')
|
55
|
+
@adapter.add relative, @type, @symProp
|
56
|
+
@adapter.add sue, relative, mary
|
57
|
+
while @re.process_rules; end
|
58
|
+
|
59
|
+
assert_equal sue, mary.relative
|
60
|
+
end
|
61
|
+
|
62
|
+
# Reasoning with owl:inverseOf.
|
63
|
+
def test_inverse_of
|
64
|
+
parentOf = Namespace.lookup(:test, 'parentOf')
|
65
|
+
hasParent = Namespace.lookup(:test, 'hasParent')
|
66
|
+
goldie = Namespace.lookup(:test, 'Goldie')
|
67
|
+
kate = Namespace.lookup(:test, 'Kate')
|
68
|
+
|
69
|
+
@adapter.add parentOf, @inverseOf, hasParent
|
70
|
+
@adapter.add goldie, parentOf, kate
|
71
|
+
while @re.process_rules; end
|
72
|
+
|
73
|
+
assert_equal goldie, kate.hasParent
|
74
|
+
end
|
75
|
+
|
76
|
+
# Inheritance of disjointness constraints.
|
77
|
+
def test_distjoint_with
|
78
|
+
plant = Namespace.lookup(:test, 'Plant')
|
79
|
+
animal = Namespace.lookup(:test, 'Animal')
|
80
|
+
mammal = Namespace.lookup(:test, 'Mammal')
|
81
|
+
|
82
|
+
@adapter.add plant, @disjointWith, animal
|
83
|
+
@adapter.add mammal, @subClassOf, animal
|
84
|
+
while @re.process_rules; end
|
85
|
+
|
86
|
+
assert plant.disjointWith.include?(mammal)
|
87
|
+
end
|
88
|
+
|
89
|
+
# When an owl:sameAs relationship is asserted or inferred between two
|
90
|
+
# entities that are known to be classes, an owl:equivalentClass
|
91
|
+
# relationship is inferred between the classes. Similarly, when an
|
92
|
+
# owl:sameAs relationship is asserted or inferred between two entities that
|
93
|
+
# are known to be properties, an owl:equivalentProperty relationship is
|
94
|
+
# inferred between the classes.
|
95
|
+
def test_equivalent_class_to_same_as
|
96
|
+
human = Namespace.lookup(:test, 'Human')
|
97
|
+
person = Namespace.lookup(:test, 'Person')
|
98
|
+
@adapter.add human, @sameAs, person
|
99
|
+
@adapter.add human, @type, @rdfclass
|
100
|
+
@adapter.add person, @type, @rdfclass
|
101
|
+
while @re.process_rules; end
|
102
|
+
|
103
|
+
assert_equal person, human.equivalentClass
|
104
|
+
end
|
105
|
+
|
106
|
+
# All the subclasses of a given class are disjoint with the class's
|
107
|
+
# complement.
|
108
|
+
def test_disjoint_with_complement
|
109
|
+
animal = Namespace.lookup(:test, 'Animal')
|
110
|
+
nonAnimals = Namespace.lookup(:test, 'NonAnimals')
|
111
|
+
mammal = Namespace.lookup(:test, 'Mammal')
|
112
|
+
@adapter.add animal, @complementOf, nonAnimals
|
113
|
+
@adapter.add mammal, @subClassOf, animal
|
114
|
+
while @re.process_rules; end
|
115
|
+
|
116
|
+
assert_equal nonAnimals, mammal.disjointWith
|
117
|
+
end
|
118
|
+
|
119
|
+
# A complicated bit of reasoning about owl:complementOf captured by
|
120
|
+
# following KIF axiom.
|
121
|
+
def test_complicated_kif_axiom
|
122
|
+
super1 = Namespace.lookup(:test, 'super1')
|
123
|
+
super2 = Namespace.lookup(:test, 'super2')
|
124
|
+
sub1 = Namespace.lookup(:test, 'sub1')
|
125
|
+
sub2 = Namespace.lookup(:test, 'sub2')
|
126
|
+
sub3 = Namespace.lookup(:test, 'sub3')
|
127
|
+
@adapter.add super1, @complementOf, super2
|
128
|
+
@adapter.add sub1, @subClassOf, super1
|
129
|
+
@adapter.add sub2, @subClassOf, super2
|
130
|
+
@adapter.add sub2, @complementOf, sub3
|
131
|
+
while @re.process_rules; end
|
132
|
+
|
133
|
+
assert sub1.subClassOf.include?(sub3)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Inferring owl:sameAs relationships via owl:FunctionalProperty and
|
137
|
+
# owl:InverseFunctionalProperty.
|
138
|
+
def test_same_as_from_functional_prop
|
139
|
+
mother = Namespace.lookup(:test, 'mother')
|
140
|
+
joe = Namespace.lookup(:test, 'Joe')
|
141
|
+
margaret = Namespace.lookup(:test, 'Margaret')
|
142
|
+
maggie = Namespace.lookup(:test, 'Maggie')
|
143
|
+
|
144
|
+
@adapter.add mother, @type, @funcProp
|
145
|
+
@adapter.add joe, mother, margaret
|
146
|
+
@adapter.add joe, mother, maggie
|
147
|
+
while @re.process_rules; end
|
148
|
+
|
149
|
+
assert margaret.sameAs.include?(maggie)
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_same_as_from_inv_functional_prop
|
153
|
+
motherOf = Namespace.lookup(:test, 'motherOf')
|
154
|
+
joe = Namespace.lookup(:test, 'Joe')
|
155
|
+
margaret = Namespace.lookup(:test, 'Margaret')
|
156
|
+
maggie = Namespace.lookup(:test, 'Maggie')
|
157
|
+
|
158
|
+
@adapter.add motherOf, @type, @invFuncProp
|
159
|
+
@adapter.add margaret, motherOf, joe
|
160
|
+
@adapter.add maggie, motherOf, joe
|
161
|
+
while @re.process_rules; end
|
162
|
+
|
163
|
+
assert margaret.sameAs.include?(maggie)
|
164
|
+
end
|
165
|
+
|
166
|
+
# If an object is rdf:type an owl:hasValue owl:Restriction, then the object
|
167
|
+
# has the specified value for the specified property.
|
168
|
+
def test_restriction_gives_value
|
169
|
+
restriction = Namespace.lookup(:test, 'RestrictionOrangeSkin')
|
170
|
+
skinColor = Namespace.lookup(:test, 'skinColor')
|
171
|
+
orange = Namespace.lookup(:test, 'Orange')
|
172
|
+
oompa = Namespace.lookup(:test, 'MrOompaLoompa')
|
173
|
+
|
174
|
+
@adapter.add restriction, @onProperty, skinColor
|
175
|
+
@adapter.add restriction, @hasValue, orange
|
176
|
+
@adapter.add oompa, @type, restriction
|
177
|
+
while @re.process_rules; end
|
178
|
+
|
179
|
+
assert_equal orange, oompa.skinColor
|
180
|
+
end
|
181
|
+
|
182
|
+
# If an owl:hasValue owl:Restriction restricts a particular property to a
|
183
|
+
# particular value, and an object has that value for that property, then
|
184
|
+
# the object has the Restriction as a type.
|
185
|
+
def test_value_gives_restriction
|
186
|
+
restriction = Namespace.lookup(:test, 'RestrictionOrangeSkin')
|
187
|
+
skinColor = Namespace.lookup(:test, 'skinColor')
|
188
|
+
orange = Namespace.lookup(:test, 'Orange')
|
189
|
+
oompa = Namespace.lookup(:test, 'MrOompaLoompa')
|
190
|
+
@adapter.add restriction, @onProperty, skinColor
|
191
|
+
@adapter.add restriction, @hasValue, orange
|
192
|
+
@adapter.add oompa, skinColor, orange
|
193
|
+
while @re.process_rules; end
|
194
|
+
|
195
|
+
assert oompa.type.collect{|t| t.class_uri}.include?(restriction)
|
196
|
+
end
|
197
|
+
|
198
|
+
# If an object is a rdf:type an owl:allValuesFrom owl:Restriction, and the
|
199
|
+
# object has values for the specified property, then the values are of the
|
200
|
+
# specified type.
|
201
|
+
def test_restriction_implies_value_type
|
202
|
+
restriction = Namespace.lookup(:test, 'RestrictionCatChildren')
|
203
|
+
child = Namespace.lookup(:test, 'child')
|
204
|
+
cat = Namespace.lookup(:test, 'Cat')
|
205
|
+
fluffy = Namespace.lookup(:test, 'Fluffy')
|
206
|
+
cupcake = Namespace.lookup(:test, 'Cupcake')
|
207
|
+
@adapter.add restriction, @onProperty, child
|
208
|
+
@adapter.add restriction, @allValuesFrom, cat
|
209
|
+
@adapter.add fluffy, @type, restriction
|
210
|
+
@adapter.add fluffy, child, cupcake
|
211
|
+
while @re.process_rules; end
|
212
|
+
|
213
|
+
assert cupcake.type.collect{|t| t.class_uri}.include?(cat)
|
214
|
+
end
|
215
|
+
|
216
|
+
# If an owl:someValuesFrom owl:Restriction restricts a particular property
|
217
|
+
# to a particular type, and if an object has some values of the specificied
|
218
|
+
# type for the specified property, then that object has the Restriction as
|
219
|
+
# a type.
|
220
|
+
def test_same_values_restriction_implies_type
|
221
|
+
restriction = Namespace.lookup(:test, 'RestrictionIvyLeagueDegree')
|
222
|
+
degree = Namespace.lookup(:test, 'degree')
|
223
|
+
mary = Namespace.lookup(:test, 'Mary')
|
224
|
+
harvard = Namespace.lookup(:test, 'Harvard')
|
225
|
+
ivy = Namespace.lookup(:test, 'IvyLeagueSchool')
|
226
|
+
@adapter.add restriction, @onProperty, degree
|
227
|
+
@adapter.add restriction, @someValuesFrom, ivy
|
228
|
+
@adapter.add mary, degree, harvard
|
229
|
+
@adapter.add harvard, @type, ivy
|
230
|
+
while @re.process_rules; end
|
231
|
+
|
232
|
+
assert mary.type.collect{|t| t.class_uri}.include?(restriction)
|
233
|
+
end
|
234
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RDFSRulebaseTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
ConnectionPool.clear
|
6
|
+
@adapter = ConnectionPool.add_data_source :type => :redland
|
7
|
+
@re = RuleEngine.new
|
8
|
+
@re.rule_base = RuleEngine::RDFSRuleBase
|
9
|
+
@type = Namespace.lookup(:rdf, 'type')
|
10
|
+
@rdfclass = Namespace.lookup(:rdfs, 'Class')
|
11
|
+
@subClassOf = Namespace.lookup(:rdfs, 'subClassOf')
|
12
|
+
@property = Namespace.lookup(:rdf, 'Property')
|
13
|
+
@subPropertyOf = Namespace.lookup(:rdfs, 'subPropertyOf')
|
14
|
+
@range = Namespace.lookup(:rdfs, 'range')
|
15
|
+
@domain = Namespace.lookup(:rdfs, 'domain')
|
16
|
+
|
17
|
+
Namespace.register(:test, 'http://test.com/')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_type_inheritance
|
21
|
+
morris = Namespace.lookup(:test, 'morris')
|
22
|
+
cat = Namespace.lookup(:test, 'cat')
|
23
|
+
mammal = Namespace.lookup(:test, 'mammal')
|
24
|
+
|
25
|
+
@adapter.add morris, @type, cat
|
26
|
+
@adapter.add cat, @subClassOf, mammal
|
27
|
+
|
28
|
+
assert @re.process_rules
|
29
|
+
assert morris.type.collect{|t| t.class_uri}.include?(mammal)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_reflexivity_sub_property
|
33
|
+
prop = Namespace.lookup(:test, 'prop')
|
34
|
+
@adapter.add prop, @type, @property
|
35
|
+
|
36
|
+
assert @re.process_rules
|
37
|
+
assert prop.subPropertyOf.include?(prop)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_reflexivity_sub_class
|
41
|
+
c = Namespace.lookup(:test, 'class')
|
42
|
+
@adapter.add c, @type, @rdfclass
|
43
|
+
|
44
|
+
assert @re.process_rules
|
45
|
+
assert c.subClassOf.include?(c)
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_type_inference_domain
|
49
|
+
teaches = Namespace.lookup(:test, 'teaches')
|
50
|
+
teacher = Namespace.lookup(:test, 'Teacher')
|
51
|
+
bob = Namespace.lookup(:test, 'Bob')
|
52
|
+
scooter = Namespace.lookup(:test, 'Scooter')
|
53
|
+
|
54
|
+
@adapter.add teaches, @domain, teacher
|
55
|
+
@adapter.add bob, teaches, scooter
|
56
|
+
|
57
|
+
assert @re.process_rules
|
58
|
+
assert bob.type.collect{|t| t.class_uri}.include?(teacher)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_type_inference_range
|
62
|
+
teaches = Namespace.lookup(:test, 'teaches')
|
63
|
+
student = Namespace.lookup(:test, 'Student')
|
64
|
+
bob = Namespace.lookup(:test, 'Bob')
|
65
|
+
scooter = Namespace.lookup(:test, 'Scooter')
|
66
|
+
|
67
|
+
@adapter.add teaches, @range, student
|
68
|
+
@adapter.add bob, teaches, scooter
|
69
|
+
|
70
|
+
assert @re.process_rules
|
71
|
+
assert scooter.type.collect{|t| t.class_uri}.include?(student)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_transitivity_sub_class
|
75
|
+
dog = Namespace.lookup(:test, 'Dog')
|
76
|
+
mammal = Namespace.lookup(:test, 'Mammal')
|
77
|
+
animal = Namespace.lookup(:test, 'Animal')
|
78
|
+
@adapter.add dog, @subClassOf, mammal
|
79
|
+
@adapter.add mammal, @subClassOf, animal
|
80
|
+
|
81
|
+
assert @re.process_rules
|
82
|
+
assert dog.subClassOf.include?(animal)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_transitivity_sub_property
|
86
|
+
parent = Namespace.lookup(:test, 'parent')
|
87
|
+
ancestor = Namespace.lookup(:test, 'ancestor')
|
88
|
+
relative = Namespace.lookup(:test, 'relative')
|
89
|
+
@adapter.add parent, @subPropertyOf, ancestor
|
90
|
+
@adapter.add ancestor, @subPropertyOf, relative
|
91
|
+
|
92
|
+
assert @re.process_rules
|
93
|
+
assert parent.subPropertyOf.include?(relative)
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RuleBaseTest < Test::Unit::TestCase
|
4
|
+
def test_to_s
|
5
|
+
rb = RuleBase.new 'RDFSRuleBase'
|
6
|
+
assert_equal 'RDFSRuleBase', rb.to_s
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_rule_to_s
|
10
|
+
r = RuleBase::Rule.new 'Test Rule'
|
11
|
+
assert_equal 'Test Rule', r.to_s
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_rule_condition
|
15
|
+
r = RuleBase::Rule.new 'Rule 1'
|
16
|
+
r.condition :x, :y, :z
|
17
|
+
assert_equal 1, r.conditions.size
|
18
|
+
assert_equal [:x, :y, :z], r.conditions[0]
|
19
|
+
r.condition RDFS::Resource.new('http://test.com/'), :y, :z
|
20
|
+
assert_equal 2, r.conditions.size
|
21
|
+
assert_equal [RDFS::Resource.new('http://test.com/'), :y, :z], r.conditions[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_rule_condition_subject_wrong_type
|
25
|
+
r = RuleBase::Rule.new 'Rule 1'
|
26
|
+
assert_raise(RuntimeError) {
|
27
|
+
r.condition 'test', :y, :z
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_rule_condition_predicate_wrong_type
|
32
|
+
r = RuleBase::Rule.new 'Rule 1'
|
33
|
+
assert_raise(RuntimeError) {
|
34
|
+
r.condition :x, 'test', :z
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_rule_conclusion
|
39
|
+
r = RuleBase::Rule.new 'Rule 1'
|
40
|
+
r.conclusion :x, :y, :z
|
41
|
+
assert_equal [:x, :y, :z], r.instance_variable_get('@conclusion')
|
42
|
+
|
43
|
+
# can only set conclusion once
|
44
|
+
assert_raise(RuntimeError) {
|
45
|
+
r.conclusion :x, :y, :z
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_rule_conclusion_subject
|
50
|
+
r = RuleBase::Rule.new 'Rule 1'
|
51
|
+
assert_raise(RuntimeError) {
|
52
|
+
r.conclusion 'test', :y, :z
|
53
|
+
}
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_rule_conclusion_predicate
|
57
|
+
r = RuleBase::Rule.new 'Rule 1'
|
58
|
+
assert_raise(RuntimeError) {
|
59
|
+
r.conclusion :x, 'test', :z
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_rule_validate
|
64
|
+
r = RuleBase::Rule.new 'Rule 1'
|
65
|
+
r.condition :x, :y, :z
|
66
|
+
r.conclusion :x, :y, :a
|
67
|
+
assert_raise(RuntimeError) {
|
68
|
+
r.validate
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_dsl
|
73
|
+
RuleBase.new 'DSLRuleBase' do
|
74
|
+
rule do
|
75
|
+
condition :x, :y, :z
|
76
|
+
|
77
|
+
conclusion :z, :y, :x
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_manual_creation
|
83
|
+
rb = RuleBase.new 'DSLRuleBase'
|
84
|
+
r = RuleBase::Rule.new 'Rule 1'
|
85
|
+
r.condition :x, :y, :z
|
86
|
+
r.conclusion :z, :y, :x
|
87
|
+
rb.rules << r
|
88
|
+
|
89
|
+
assert_equal 1, rb.rules.size
|
90
|
+
assert_equal r, rb.rules[0]
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_auto_validation
|
94
|
+
assert_raise(RuntimeError) {
|
95
|
+
RuleBase.new 'RDFSRuleBase' do
|
96
|
+
rule do
|
97
|
+
condition :x, :y, :z
|
98
|
+
conclusion :x, :y, :a
|
99
|
+
end
|
100
|
+
end
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RuleEngineMixinTest < Test::Unit::TestCase
|
4
|
+
def test_auto_fire
|
5
|
+
adapter = ConnectionPool.add_data_source :type => :redland
|
6
|
+
class << adapter
|
7
|
+
include RuleEngineMixin
|
8
|
+
end
|
9
|
+
adapter.rule_engine = RuleEngine.new(:rule_base => RuleEngine::RDFSRuleBase)
|
10
|
+
subProp = Namespace.lookup(:rdfs, 'subPropertyOf')
|
11
|
+
one = RDFS::Resource.new('http://test.com/one')
|
12
|
+
two = RDFS::Resource.new('http://test.com/two')
|
13
|
+
three = RDFS::Resource.new('http://test.com/three')
|
14
|
+
adapter.add(one, subProp, two)
|
15
|
+
adapter.add(two, subProp, three)
|
16
|
+
|
17
|
+
assert one.subPropertyOf.include?(three)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper'
|
2
|
+
|
3
|
+
class RuleEngineTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
ConnectionPool.clear
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_process_rules
|
9
|
+
subProp = Namespace.lookup(:rdfs, 'subPropertyOf')
|
10
|
+
re = RuleEngine.new
|
11
|
+
re.define_rules do
|
12
|
+
rule do
|
13
|
+
condition :x, subProp, :y
|
14
|
+
condition :y, subProp, :z
|
15
|
+
|
16
|
+
conclusion :x, subProp, :z
|
17
|
+
end
|
18
|
+
end
|
19
|
+
adapter = ConnectionPool.add_data_source :type => :redland
|
20
|
+
one = RDFS::Resource.new('http://one')
|
21
|
+
two = RDFS::Resource.new('http://two')
|
22
|
+
three = RDFS::Resource.new('http://three')
|
23
|
+
adapter.add(one, subProp, two)
|
24
|
+
adapter.add(two, subProp, three)
|
25
|
+
|
26
|
+
assert re.process_rules
|
27
|
+
assert_equal 3, adapter.size
|
28
|
+
p three.subPropertyOf
|
29
|
+
assert one.subPropertyOf.include?(three)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_define_rulebase_with_existing
|
33
|
+
re = RuleEngine.new
|
34
|
+
re.rule_base = RuleEngine::RDFSRuleBase
|
35
|
+
assert_equal 7, re.rule_base.rules.size
|
36
|
+
re.define_rules do
|
37
|
+
rule do
|
38
|
+
condition :x, :y, :z
|
39
|
+
conclusion :x, :z, 'test'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
assert_equal 8, re.rule_base.rules.size
|
43
|
+
assert_equal 7, RuleEngine::RDFSRuleBase.rules.size
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_set_rulebase
|
47
|
+
re = RuleEngine.new
|
48
|
+
re.rule_base = RuleEngine::RDFSRuleBase
|
49
|
+
assert_equal 7, re.rule_base.rules.size
|
50
|
+
re.rule_base = RuleBase.new do
|
51
|
+
rule do
|
52
|
+
condition :x, :y, :z
|
53
|
+
conclusion :x, :z, 'test'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
assert_equal 8, re.rule_base.rules.size
|
57
|
+
assert_equal 7, RuleEngine::RDFSRuleBase.rules.size
|
58
|
+
end
|
59
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'active_rdf'
|
4
|
+
$activerdflog.level = Logger::DEBUG
|
5
|
+
|
6
|
+
$log_final = nil # HACK this is just to get rid of the redland warning messages
|
7
|
+
|
8
|
+
lib = File.dirname(__FILE__) + '/../lib/'
|
9
|
+
require lib + 'activerdf_rules/rule_base'
|
10
|
+
require lib + 'activerdf_rules/rule_engine'
|
11
|
+
require lib + 'activerdf_rules/rule_engine_mixin'
|
metadata
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: activerdf_rules
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2006-12-21 00:00:00 -05:00
|
8
|
+
summary: A rulebase and forward chaining production system for activerdf databases
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: paul@stadig.name
|
12
|
+
homepage: http://activerdf-rules.rubyforge.org
|
13
|
+
rubyforge_project: activerdf-rules
|
14
|
+
description: A rulebase and forward chaining production system for activerdf databases
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- pjstadig
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- Rakefile
|
36
|
+
- setup.rb
|
37
|
+
- examples/person_example.rb
|
38
|
+
- lib/activerdf_rules.rb
|
39
|
+
- lib/activerdf_rules/rule_base.rb
|
40
|
+
- lib/activerdf_rules/rule_engine_mixin.rb
|
41
|
+
- lib/activerdf_rules/rule_engine.rb
|
42
|
+
- lib/activerdf_rules/version.rb
|
43
|
+
- test/test_helper.rb
|
44
|
+
- test/activerdf_rules_test.rb
|
45
|
+
test_files:
|
46
|
+
- test/activerdf_rules_test.rb
|
47
|
+
- test/activerdf_rules/rdfs_rulebase_test.rb
|
48
|
+
- test/activerdf_rules/rule_base_test.rb
|
49
|
+
- test/activerdf_rules/rule_engine_mixin_test.rb
|
50
|
+
- test/activerdf_rules/rule_engine_test.rb
|
51
|
+
- test/activerdf_rules/owl_rulebase_test.rb
|
52
|
+
rdoc_options: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
executables: []
|
57
|
+
|
58
|
+
extensions: []
|
59
|
+
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
dependencies:
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: hoe
|
65
|
+
version_requirement:
|
66
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
67
|
+
requirements:
|
68
|
+
- - ">="
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.1.6
|
71
|
+
version:
|