Skip to content

Commit 13814b0

Browse files
committed
TripleStoreReasoner enhancement
1 parent 3fce2bb commit 13814b0

File tree

1 file changed

+56
-30
lines changed

1 file changed

+56
-30
lines changed

ontolearn/triple_store.py

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import re
44
from itertools import chain
5-
from typing import Iterable
5+
from typing import Iterable, Set
66
import requests
77
from requests import Response
88
from requests.exceptions import RequestException, JSONDecodeError
@@ -67,7 +67,7 @@ def get_results_from_ts(triplestore_address: str, query: str, return_type: type)
6767
if return_type == OWLLiteral:
6868
yield from unwrap(response)
6969
else:
70-
yield from [return_type(i) for i in unwrap(response)]
70+
yield from [return_type(i) for i in unwrap(response) if i is not None]
7171
# return [return_type(IRI.create(i['x']['value'])) for i in
7272
# response.json()['results']['bindings']]
7373
except JSONDecodeError as e:
@@ -84,12 +84,15 @@ def unwrap(result: Response):
8484
for v in vars_:
8585
if b[v]['type'] == 'uri':
8686
val.append(IRI.create(b[v]['value']))
87+
elif b[v]['type'] == 'bnode':
88+
continue
8789
else:
90+
print(b[v]['type'])
8891
val.append(OWLLiteral(b[v]['value'], OWLDatatype(IRI.create(b[v]['datatype']))))
8992
if len(val) == 1:
9093
yield val.pop()
9194
else:
92-
yield tuple(val)
95+
yield None
9396

9497

9598
def suf(direct: bool):
@@ -199,30 +202,31 @@ def __init__(self, ontology: TripleStoreOntology):
199202

200203
def data_property_domains(self, pe: OWLDataProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
201204
domains = {d.get_domain() for d in self.ontology.data_property_domain_axioms(pe)}
202-
super_domains = set(chain.from_iterable([self.super_classes(d) for d in domains]))
203-
yield from domains - super_domains
205+
sub_domains = set(chain.from_iterable([self.sub_classes(d) for d in domains]))
206+
yield from domains - sub_domains
204207
if not direct:
205-
yield from super_domains
208+
yield from sub_domains
206209

207210
def object_property_domains(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
208211
domains = {d.get_domain() for d in self.ontology.object_property_domain_axioms(pe)}
209-
super_domains = set(chain.from_iterable([self.super_classes(d) for d in domains]))
210-
yield from domains - super_domains
212+
sub_domains = set(chain.from_iterable([self.sub_classes(d) for d in domains]))
213+
yield from domains - sub_domains
211214
if not direct:
212-
yield from super_domains
215+
yield from sub_domains
213216

214217
def object_property_ranges(self, pe: OWLObjectProperty, direct: bool = False) -> Iterable[OWLClassExpression]:
215218
ranges = {r.get_range() for r in self.ontology.object_property_range_axioms(pe)}
216-
super_ranges = set(chain.from_iterable([self.super_classes(d) for d in ranges]))
217-
yield from ranges - super_ranges
219+
sub_ranges = set(chain.from_iterable([self.sub_classes(d) for d in ranges]))
220+
yield from ranges - sub_ranges
218221
if not direct:
219-
yield from super_ranges
222+
yield from sub_ranges
220223

221224
def equivalent_classes(self, ce: OWLClassExpression, only_named: bool = True) -> Iterable[OWLClassExpression]:
222225
if only_named:
223226
if isinstance(ce, OWLClass):
224-
query = owl_prefix + "SELECT DISTINCT ?x" + \
225-
"WHERE { ?x owl:equivalentClass " + f"<{ce.get_iri().as_str()}>." + \
227+
query = owl_prefix + "SELECT DISTINCT ?x " + \
228+
"WHERE { {?x owl:equivalentClass " + f"<{ce.get_iri().as_str()}>.}}" + \
229+
"UNION {" + f"<{ce.get_iri().as_str()}>" + " owl:equivalentClass ?x.}" + \
226230
"FILTER(?x != " + f"<{ce.get_iri().as_str()}>)}}"
227231
yield from get_results_from_ts(self.url, query, OWLClass)
228232
else:
@@ -242,31 +246,37 @@ def disjoint_classes(self, ce: OWLClassExpression, only_named: bool = True) -> I
242246
raise NotImplementedError("Finding disjoint complex classes is not implemented")
243247

244248
def different_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]:
245-
query = owl_prefix + "SELECT DISTINCT ?x" + \
246-
"WHERE { ?x owl:distinctMembers " + f"<{ind.str}>" + " .}"
249+
query = owl_prefix + rdf_prefix + "SELECT DISTINCT ?x \n" + \
250+
"WHERE{ ?allDifferent owl:distinctMembers/rdf:rest*/rdf:first ?x.\n" + \
251+
"?allDifferent owl:distinctMembers/rdf:rest*/rdf:first" + f"<{ind.str}>" + ".\n" + \
252+
"FILTER(?x != " + f"<{ind.str}>" + ")}"
247253
yield from get_results_from_ts(self.url, query, OWLNamedIndividual)
248254

249255
def same_individuals(self, ind: OWLNamedIndividual) -> Iterable[OWLNamedIndividual]:
250-
query = owl_prefix + "SELECT DISTINCT ?x" + \
251-
"WHERE { ?x owl:sameAs " + f"<{ind.str}>" + " .}"
256+
query = owl_prefix + "SELECT DISTINCT ?x " + \
257+
"WHERE {{ ?x owl:sameAs " + f"<{ind.str}>" + " .}" + \
258+
"UNION { " + f"<{ind.str}>" + " owl:sameAs ?x.}}"
252259
yield from get_results_from_ts(self.url, query, OWLNamedIndividual)
253260

254261
def equivalent_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]:
255262
if isinstance(op, OWLObjectProperty):
256-
query = owl_prefix + "SELECT DISTINCT ?x" + \
257-
"WHERE { ?x owl:equivalentProperty " + f"<{op.get_iri().as_str()}>." + \
263+
query = owl_prefix + "SELECT DISTINCT ?x " + \
264+
"WHERE { {?x owl:equivalentProperty " + f"<{op.get_iri().as_str()}>.}}" + \
265+
"UNION {" + f"<{op.get_iri().as_str()}>" + " owl:equivalentProperty ?x.}" + \
258266
"FILTER(?x != " + f"<{op.get_iri().as_str()}>)}}"
259267
yield from get_results_from_ts(self.url, query, OWLObjectProperty)
260268
elif isinstance(op, OWLObjectInverseOf):
261-
query = owl_prefix + "SELECT DISTINCT ?x" + \
269+
query = owl_prefix + "SELECT DISTINCT ?x " + \
262270
"WHERE { ?inverseProperty owl:inverseOf " + f"<{op.get_inverse().get_iri().as_str()}> ." + \
263-
" ?x owl:equivalentProperty ?inverseProperty ." + \
271+
" {?x owl:equivalentProperty ?inverseProperty .}" + \
272+
"UNION { ?inverseProperty owl:equivalentClass ?x.}" + \
264273
"FILTER(?x != ?inverseProperty }>)}"
265274
yield from get_results_from_ts(self.url, query, OWLObjectProperty)
266275

267276
def equivalent_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]:
268277
query = owl_prefix + "SELECT DISTINCT ?x" + \
269-
"WHERE { ?x owl:equivalentProperty " + f"<{dp.get_iri().as_str()}>." + \
278+
"WHERE { {?x owl:equivalentProperty " + f"<{dp.get_iri().as_str()}>.}}" + \
279+
"UNION {" + f"<{dp.get_iri().as_str()}>" + " owl:equivalentProperty ?x.}" + \
270280
"FILTER(?x != " + f"<{dp.get_iri().as_str()}>)}}"
271281
yield from get_results_from_ts(self.url, query, OWLDataProperty)
272282

@@ -295,12 +305,21 @@ def object_property_values(self, ind: OWLNamedIndividual, pe: OWLObjectPropertyE
295305
def flush(self) -> None:
296306
pass
297307

298-
def instances(self, ce: OWLClassExpression, direct: bool = False) -> Iterable[OWLNamedIndividual]:
308+
def instances(self, ce: OWLClassExpression, direct: bool = False, seen_set: Set = None) \
309+
-> Iterable[OWLNamedIndividual]:
310+
if not seen_set:
311+
seen_set = set()
312+
seen_set.add(ce)
299313
ce_to_sparql = self._owl2sparql_converter.as_query("?x", ce)
300314
if not direct:
301315
ce_to_sparql = ce_to_sparql.replace("?x a ", "?x a ?some_cls. \n ?some_cls "
302316
"<http://www.w3.org/2000/01/rdf-schema#subClassOf>* ")
303317
yield from get_results_from_ts(self.url, ce_to_sparql, OWLNamedIndividual)
318+
if not direct:
319+
for cls in self.equivalent_classes(ce):
320+
if cls not in seen_set:
321+
seen_set.add(cls)
322+
yield from self.instances(cls, direct, seen_set)
304323

305324
def sub_classes(self, ce: OWLClassExpression, direct: bool = False, only_named: bool = True) \
306325
-> Iterable[OWLClassExpression]:
@@ -345,18 +364,24 @@ def super_classes(self, ce: OWLClassExpression, direct: bool = False, only_named
345364

346365
def disjoint_object_properties(self, op: OWLObjectPropertyExpression) -> Iterable[OWLObjectPropertyExpression]:
347366
if isinstance(op, OWLObjectProperty):
348-
query = owl_prefix + " SELECT DISTINCT ?x " + \
349-
"WHERE { " + f"<{op.get_iri().as_str()}>" + " owl:propertyDisjointWith ?x .}"
367+
query = owl_prefix + rdf_prefix + "SELECT DISTINCT ?x \n" + \
368+
"WHERE{ ?AllDisjointProperties owl:members/rdf:rest*/rdf:first ?x.\n" + \
369+
"?AllDisjointProperties owl:members/rdf:rest*/rdf:first" + f"<{op.get_iri().as_str()}>" + ".\n" + \
370+
"FILTER(?x != " + f"<{op.get_iri().as_str()}>" + ")}"
350371
yield from get_results_from_ts(self.url, query, OWLObjectProperty)
351372
elif isinstance(op, OWLObjectInverseOf):
352373
query = owl_prefix + " SELECT DISTINCT ?x " + \
353374
"WHERE { ?inverseProperty owl:inverseOf " + f"<{op.get_inverse().get_iri().as_str()}> ." + \
354-
" ?x owl:propertyDisjointWith ?inverseProperty .}"
375+
" ?AllDisjointProperties owl:members/rdf:rest*/rdf:first ?x.\n" + \
376+
" ?AllDisjointProperties owl:members/rdf:rest*/rdf:first ?inverseProperty.\n" + \
377+
" FILTER(?x != ?inverseProperty)}"
355378
yield from get_results_from_ts(self.url, query, OWLObjectProperty)
356379

357380
def disjoint_data_properties(self, dp: OWLDataProperty) -> Iterable[OWLDataProperty]:
358-
query = owl_prefix + " SELECT DISTINCT ?x " + \
359-
"WHERE { " + f"<{dp.get_iri().as_str()}>" + " owl:propertyDisjointWith ?x .}"
381+
query = owl_prefix + rdf_prefix + "SELECT DISTINCT ?x \n" + \
382+
"WHERE{ ?AllDisjointProperties owl:members/rdf:rest*/rdf:first ?x.\n" + \
383+
"?AllDisjointProperties owl:members/rdf:rest*/rdf:first" + f"<{dp.get_iri().as_str()}>" + ".\n" + \
384+
"FILTER(?x != " + f"<{dp.get_iri().as_str()}>" + ")}"
360385
yield from get_results_from_ts(self.url, query, OWLDataProperty)
361386

362387
def all_data_property_values(self, pe: OWLDataProperty, direct: bool = True) -> Iterable[OWLLiteral]:
@@ -406,7 +431,8 @@ def types(self, ind: OWLNamedIndividual, direct: bool = False) -> Iterable[OWLCl
406431
else:
407432
query = rdfs_prefix + "SELECT DISTINCT ?x WHERE {" + f"<{ind.str}> a ?cls. " \
408433
" ?cls rdfs:subClassOf* ?x}"
409-
yield from get_results_from_ts(self.url, query, OWLClass)
434+
yield from [i for i in get_results_from_ts(self.url, query, OWLClass)
435+
if i != OWLClass(IRI('http://www.w3.org/2002/07/owl#', 'NamedIndividual'))]
410436

411437
def get_root_ontology(self) -> OWLOntology:
412438
return self.ontology

0 commit comments

Comments
 (0)