Start implementing infering triples.
[htsworkflow.git] / htsworkflow / util / test / test_rdfinfer.py
1 import unittest
2
3 import RDF
4
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
9
10 foafNS = RDF.NS('http://xmlns.com/foaf/0.1/')
11
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/> .
17
18
19 foaf:Agent
20      a rdfs:Class, owl:Class ;
21      rdfs:comment "An agent (person, group, software or physical artifiact)."@en;
22      rdfs:label "Agent" .
23
24 foaf:Person
25      a rdfs:Class, owl:Class, foaf:Agent ;
26      rdfs:label "Person" .
27
28 foaf:age
29      a rdf:Property, owl:DatatypeProperty, owl:FunctionalProperty ;
30      rdfs:comment "The age in years of some agent." ;
31      rdfs:domain foaf:Agent ;
32      rdfs:label "age";
33      rdfs:range rdfs:Literal .
34
35 foaf:familyName
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 .
41
42 foaf:firstName
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 .
48
49 foaf:Document
50      a rdfs:Class, owl:Class ;
51      rdfs:comment "A document." .
52
53 foaf:Image
54      a rdfs:Class, owl:Class ;
55      rdfs:comment "An image." ;
56      rdfs:subClassOf foaf:Document .
57
58 foaf:depicts
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 .
64
65 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 .
71 """
72
73 FOAF_DATA = """
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/> .
78
79 _:me
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> .
85
86 <http://example.org/me.jpg>
87      a foaf:Image, owl:Thing ;
88      foaf:depicts _:me .
89 """
90
91 class TestInfer(unittest.TestCase):
92     def setUp(self):
93         self.model = get_model()
94         add_default_schemas(self.model)
95         load_string_into_model(self.model, 'turtle', MINI_FOAF_ONTOLOGY)
96
97     def test_inverse_of(self):
98         fooNS = RDF.NS('http://example.org/')
99         load_string_into_model(self.model, 'turtle', FOAF_DATA)
100         inference = Infer(self.model)
101         depiction = RDF.Statement(None,
102                                   foafNS['depiction'],
103                                   fooNS['me.jpg'])
104         size = self.model.size()
105         found_statements = list(self.model.find_statements(depiction))
106         self.assertEqual(len(found_statements), 0)
107         inference._rule_inverse_of()
108         found_statements = list(self.model.find_statements(depiction))
109         self.assertEqual(len(found_statements), 1)
110
111         # we should've added one statement.
112         self.assertEqual(self.model.size(), size + 1)
113
114         size = self.model.size()
115         inference._rule_inverse_of()
116         # we should already have both versions in our model
117         self.assertEqual(self.model.size(), size)
118
119     def test_validate_types(self):
120         fooNS = RDF.NS('http://example.org/')
121         load_string_into_model(self.model, 'turtle', FOAF_DATA)
122         inference = Infer(self.model)
123
124         errors = list(inference._validate_types())
125         self.assertEqual(len(errors), 0)
126
127         s = RDF.Statement(fooNS['document'],
128                           dcNS['title'],
129                           RDF.Node("bleem"))
130         self.model.append(s)
131         errors = list(inference._validate_types())
132         self.assertEqual(len(errors), 1)
133
134     def test_validate_undefined_properties(self):
135         fooNS = RDF.NS('http://example.org/')
136         inference = Infer(self.model)
137
138         errors = list(inference._validate_undefined_properties())
139         self.assertEqual(len(errors), 0)
140
141         load_string_into_model(self.model, 'turtle', FOAF_DATA)
142
143         errors = list(inference._validate_undefined_properties())
144         self.assertEqual(len(errors), 2)
145
146
147     def test_validate_undefined_properties(self):
148         fooNS = RDF.NS('http://example.org/')
149         foafNS = RDF.NS('http://xmlns.com/foaf/0.1/')
150         load_string_into_model(self.model, 'turtle', FOAF_DATA)
151         inference = Infer(self.model)
152
153         errors = list(inference._validate_property_types())
154         self.assertEqual(len(errors), 0)
155
156         s = RDF.Statement(fooNS['me.jpg'],
157                           foafNS['firstName'],
158                           RDF.Node("name"))
159         self.model.append(s)
160         errors = list(inference._validate_property_types())
161         self.assertEqual(len(errors), 1)
162         self.assertTrue(errors[0].startswith('Domain of http://example.org'))
163         del self.model[s]
164
165         errors = list(inference._validate_property_types())
166         self.assertEqual(len(errors), 0)
167         s = RDF.Statement(fooNS['foo.txt'], rdfNS['type'], foafNS['Document'])
168         self.model.append(s)
169         s = RDF.Statement(fooNS['me.jpg'],
170                           foafNS['depicts'],
171                           foafNS['foo.txt'])
172         self.model.append(s)
173
174         errors = list(inference._validate_property_types())
175         self.assertEqual(len(errors), 1)
176         self.assertTrue(errors[0].startswith('Range of http://example.org'))
177         del self.model[s]
178
179 def suite():
180     return unittest.makeSuite(TestInfer, 'test')
181
182 if __name__ == "__main__":
183     unittest.main(defaultTest='suite')