Improve code for working with an ontology

This commit is contained in:
Aleksey Filippov 2023-06-03 00:18:51 +04:00
parent 8312150a62
commit 3eb01b064c

View File

@ -1,58 +1,61 @@
from typing import List
from typing import List, Set
from ordered_set import OrderedSet
from owlready2 import get_ontology, Ontology
class MyOntology:
def __init__(self) -> None:
self.__onto: Ontology = get_ontology("file://./new-ontology.owx").load()
self.__concept = self.__onto.Concept
def __get_parent_with_hierarchy(self, root, parents):
pdict = {}
for parent in parents:
level = 0
subclass = parent.is_a[0]
if subclass == self.__onto.Concept and len(pdict.keys()) == 0:
pdict[1] = [parent]
while subclass != self.__onto.Concept:
level += 1
if subclass == root:
if pdict.get(level) is None:
pdict[level] = []
pdict[level].append(parent)
subclass = subclass.is_a[0]
keys = sorted(pdict.keys())
if len(keys) == 0:
return None, None
return keys[-1], pdict[keys[-1]]
def __get_concept_level(self, concept) -> int:
level = 1
parent = concept.is_a[0]
while parent != self.__concept:
level += 1
parent = parent.is_a[0]
return level
def __find_instance(self, root, level: int, terms: List[str]) -> OrderedSet[(int, [])]:
level += 1
instances: OrderedSet[(int, [])] = OrderedSet()
for current_class in root.subclasses():
for instance in current_class.instances():
if instance.name == terms[-1] is not None:
plevel, parents = self.__get_parent_with_hierarchy(current_class, instance.is_instance_of)
filtered_terms = list(filter(lambda term: term != terms[-1], terms))
if parents is None:
plevel = level
parents = [current_class]
if len(filtered_terms) == 0:
instances.append((plevel, current_class))
return instances
for parent in parents:
result = self.__find_instance(parent, plevel, filtered_terms)
if len(result) == 0:
instances.append((plevel, parent))
else:
[instances.append(item) for item in result]
@staticmethod
def __get_instances(root, term: str) -> Set:
instances: Set = set()
for instance in root.instances():
if instance.name == term:
instances.add(instance)
return instances
def get_event_description(self, terms: List[str]) -> str:
instances = OrderedSet()
def __get_concepts(self, instances: Set) -> Set:
concepts: Set = set()
for instance in instances:
for concept in instance.is_instance_of:
concepts.add((self.__get_concept_level(concept), concept))
return concepts
def make(self, root_class: [], terms: List[str], is_empty=True) -> Set:
if not isinstance(terms, list) or not isinstance(root_class, list):
return set()
if len(terms) == 0 or len(root_class) == 0:
return set()
concepts: Set = set()
for concept in root_class:
term: str = terms[-1]
my_terms: List[str] = list(filter(lambda item: item != term, terms))
instances: Set = self.__get_instances(concept, term)
result = self.__get_concepts(instances)
concepts.update(result)
new_root: [] = []
is_empty = is_empty and len(concepts) == 0
if len(result) == 0 and is_empty:
new_root.append(self.__concept)
else:
new_root.extend(list(map(lambda item: item[1], result)))
concepts.update(self.make(new_root, my_terms, is_empty))
return concepts
def get_events(self, terms: List[str]) -> str:
concepts: Set = set()
for term in terms:
for item in self.__find_instance(self.__onto.Concept, 0, term.split(' ')):
instances.append(item)
instances = sorted(list(instances), reverse=True)
return '\n'.join(list(map(lambda instance: ' '.join(instance[1].hasDescription), instances)))
concepts.update(self.make([self.__concept], term.split(' ')))
events = sorted(list(
map(lambda concept: (concept[0], ' '.join(concept[1].hasDescription)), concepts)), reverse=True)
return '\n'.join(list(map(lambda event: event[1], events)))