5 from htsworkflow.util.rdfhelp import get_model, \
6 add_default_schemas, add_schema, load_string_into_model, dump_model
7 from htsworkflow.util.rdfns import *
8 from htsworkflow.util.rdfinfer import Infer
10 foafNS = RDF.NS('http://xmlns.com/foaf/0.1/')
12 MINI_FOAF_ONTOLOGY = """
13 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
14 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
15 @prefix owl: <http://www.w3.org/2002/07/owl#> .
16 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
20 a rdfs:Class, owl:Class ;
21 rdfs:comment "An agent (person, group, software or physical artifiact)."@en;
25 a rdfs:Class, owl:Class, foaf:Agent ;
29 a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ;
30 rdfs:comment "The age in years of some agent." ;
31 rdfs:domain foaf:Agent ;
33 rdfs:range rdfs:Literal .
36 a rdf:Property, owl:DatatypeProperty ;
37 rdfs:comment "Family name of some person." ;
38 rdfs:label "familyName" ;
39 rdfs:domain foaf:Person ;
40 rdfs:range rdfs:Literal .
43 a rdf:Property, owl:DatatypeProperty ;
44 rdfs:comment "the first name of a person." ;
45 rdfs:domain foaf:Person ;
46 rdfs:label "firstname" ;
47 rdfs:range rdfs:Literal .
50 a rdfs:Class, owl:Class ;
51 rdfs:comment "A document." .
54 a rdfs:Class, owl:Class ;
55 rdfs:comment "An image." ;
56 rdfs:subClassOf foaf:Document .
59 a rdf:Property, owl:ObjectProperty ;
60 rdfs:comment "A thing depicted in this representation." ;
61 rdfs:domain foaf:Image ;
62 rdfs:range owl:Thing ;
63 owl:inverseOf foaf:depiction .
66 a rdf:Property, owl:ObjectProperty ;
67 rdfs:comment "Depiction of some thing." ;
68 rdfs:domain owl:Thing ;
69 rdfs:range foaf:Image ;
70 owl:inverseOf foaf:depicts .
74 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
75 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
76 @prefix owl: <http://www.w3.org/2002/07/owl#> .
77 @prefix foaf: <http://xmlns.com/foaf/0.1/> .
80 foaf:firstName "Diane" ;
81 foaf:familyName "Trout" ;
82 a foaf:Person, owl:Thing ;
83 <http://example.org/other_literal> "value" ;
84 <http://example.org/other_resource> <http://example.org/resource> .
86 <http://example.org/me.jpg>
87 a foaf:Image, owl:Thing ;
91 class TestInfer(unittest.TestCase):
93 self.model = get_model()
94 add_default_schemas(self.model)
95 load_string_into_model(self.model, 'turtle', MINI_FOAF_ONTOLOGY)
98 fooNS = RDF.NS('http://example.org/')
99 load_string_into_model(self.model, 'turtle', FOAF_DATA)
100 inference = Infer(self.model)
102 s = RDF.Statement(fooNS['me.jpg'], rdfNS['type'], rdfsNS['Class'])
103 found = list(self.model.find_statements(s))
104 self.assertEqual(len(found), 0)
105 inference._rule_class()
106 s = RDF.Statement(fooNS['me.jpg'], rdfNS['type'], rdfsNS['Class'])
107 found = list(self.model.find_statements(s))
108 self.assertEqual(len(found), 1)
110 def test_inverse_of(self):
111 fooNS = RDF.NS('http://example.org/')
112 load_string_into_model(self.model, 'turtle', FOAF_DATA)
113 inference = Infer(self.model)
114 depiction = RDF.Statement(None,
117 size = self.model.size()
118 found_statements = list(self.model.find_statements(depiction))
119 self.assertEqual(len(found_statements), 0)
120 inference._rule_inverse_of()
121 found_statements = list(self.model.find_statements(depiction))
122 self.assertEqual(len(found_statements), 1)
124 # we should've added one statement.
125 self.assertEqual(self.model.size(), size + 1)
127 size = self.model.size()
128 inference._rule_inverse_of()
129 # we should already have both versions in our model
130 self.assertEqual(self.model.size(), size)
132 def test_validate_types(self):
133 fooNS = RDF.NS('http://example.org/')
134 load_string_into_model(self.model, 'turtle', FOAF_DATA)
135 inference = Infer(self.model)
137 errors = list(inference._validate_types())
138 self.assertEqual(len(errors), 0)
140 s = RDF.Statement(fooNS['document'],
144 errors = list(inference._validate_types())
145 self.assertEqual(len(errors), 1)
147 def test_validate_undefined_properties(self):
148 fooNS = RDF.NS('http://example.org/')
149 inference = Infer(self.model)
151 errors = list(inference._validate_undefined_properties())
152 self.assertEqual(len(errors), 0)
154 load_string_into_model(self.model, 'turtle', FOAF_DATA)
156 errors = list(inference._validate_undefined_properties())
157 self.assertEqual(len(errors), 2)
160 def test_validate_undefined_properties(self):
161 fooNS = RDF.NS('http://example.org/')
162 foafNS = RDF.NS('http://xmlns.com/foaf/0.1/')
163 load_string_into_model(self.model, 'turtle', FOAF_DATA)
164 inference = Infer(self.model)
166 errors = list(inference._validate_property_types())
167 self.assertEqual(len(errors), 0)
169 s = RDF.Statement(fooNS['me.jpg'],
173 errors = list(inference._validate_property_types())
174 self.assertEqual(len(errors), 1)
175 startswith = 'Domain of '
176 self.assertEqual(errors[0][:len(startswith)], startswith)
177 self.assertTrue('http://example.org/me.jpg' in errors[0])
178 endswith = 'http://xmlns.com/foaf/0.1/Person'
179 self.assertEqual(errors[0][-len(endswith):], endswith)
182 errors = list(inference._validate_property_types())
183 self.assertEqual(len(errors), 0)
184 s = RDF.Statement(fooNS['foo.txt'], rdfNS['type'], foafNS['Document'])
186 s = RDF.Statement(fooNS['me.jpg'],
191 errors = list(inference._validate_property_types())
192 self.assertEqual(len(errors), 1)
193 startswith = 'Range of '
194 self.assertEqual(errors[0][:len(startswith)], startswith)
195 self.assertTrue('http://example.org/me.jpg' in errors[0])
196 endswith = 'http://www.w3.org/2002/07/owl#Thing'
197 self.assertEqual(errors[0][-len(endswith):], endswith)
200 def test_property_multiple_domain_types(self):
201 """Can we process a property with multiple domain types?
204 @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
205 @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
206 @prefix foo: <http://example.org/> .
207 @prefix bar: <http://example.com/> .
209 foo:AClass a rdfs:Class .
210 foo:BClass a rdfs:Class .
211 bar:ABarClass a rdfs:Class .
213 foo:aprop a rdf:Property ;
214 rdfs:domain foo:AClass ;
215 rdfs:domain bar:ABarClass ;
216 rdfs:range foo:BClass .
218 foo:object a foo:BClass .
219 foo:subject a foo:AClass ;
220 foo:aprop foo:object .
221 bar:subject a bar:ABarClass ;
222 foo:aprop foo:object .
224 load_string_into_model(self.model, 'turtle', turtle)
225 inference = Infer(self.model)
227 errmsg = list(inference._validate_property_types())
229 self.failUnlessEqual(len(errmsg), 0)
232 return unittest.makeSuite(TestInfer, 'test')
234 if __name__ == "__main__":
235 unittest.main(defaultTest='suite')