fuzzy-dl-owl2 1.0.0__py3-none-any.whl
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.
- fuzzy_dl_owl2/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/__init__.py +23 -0
- fuzzy_dl_owl2/fuzzydl/assertion/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/assertion/assertion.py +72 -0
- fuzzy_dl_owl2/fuzzydl/assertion/atomic_assertion.py +19 -0
- fuzzy_dl_owl2/fuzzydl/concept/__init__.py +13 -0
- fuzzy_dl_owl2/fuzzydl/concept/all_some_concept.py +85 -0
- fuzzy_dl_owl2/fuzzydl/concept/approximation_concept.py +147 -0
- fuzzy_dl_owl2/fuzzydl/concept/atomic_concept.py +91 -0
- fuzzy_dl_owl2/fuzzydl/concept/choquet_integral.py +64 -0
- fuzzy_dl_owl2/fuzzydl/concept/concept.py +230 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/__init__.py +10 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/crisp_concrete_concept.py +60 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_concrete_concept.py +63 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +127 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/left_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/linear_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/modified_concrete_concept.py +66 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/right_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +96 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/triangular_concrete_concept.py +89 -0
- fuzzy_dl_owl2/fuzzydl/concept/ext_threshold_concept.py +77 -0
- fuzzy_dl_owl2/fuzzydl/concept/has_value_concept.py +51 -0
- fuzzy_dl_owl2/fuzzydl/concept/implies_concept.py +144 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/__init__.py +6 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_concept_interface.py +17 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_concepts_interface.py +18 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_concept_interface.py +14 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_interface.py +15 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_value_interface.py +21 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_weighted_concepts_interface.py +29 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/linearly_modified_concept.py +32 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/modified_concept.py +59 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/triangularly_modified_concept.py +33 -0
- fuzzy_dl_owl2/fuzzydl/concept/negated_nominal.py +42 -0
- fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +707 -0
- fuzzy_dl_owl2/fuzzydl/concept/owa_concept.py +57 -0
- fuzzy_dl_owl2/fuzzydl/concept/qowa_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept/quasi_sugeno_integral.py +46 -0
- fuzzy_dl_owl2/fuzzydl/concept/self_concept.py +45 -0
- fuzzy_dl_owl2/fuzzydl/concept/string_concept.py +35 -0
- fuzzy_dl_owl2/fuzzydl/concept/sugeno_integral.py +83 -0
- fuzzy_dl_owl2/fuzzydl/concept/threshold_concept.py +81 -0
- fuzzy_dl_owl2/fuzzydl/concept/truth_concept.py +83 -0
- fuzzy_dl_owl2/fuzzydl/concept/value_concept.py +67 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_concept.py +55 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_max_concept.py +63 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_min_concept.py +57 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_zero_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept_equivalence.py +20 -0
- fuzzy_dl_owl2/fuzzydl/concrete_feature.py +94 -0
- fuzzy_dl_owl2/fuzzydl/degree/__init__.py +4 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree.py +79 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_expression.py +57 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_numeric.py +57 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_variable.py +54 -0
- fuzzy_dl_owl2/fuzzydl/domain_axiom.py +8 -0
- fuzzy_dl_owl2/fuzzydl/exception/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/exception/fuzzy_ontology_exception.py +4 -0
- fuzzy_dl_owl2/fuzzydl/exception/inconsistent_ontology_exception.py +4 -0
- fuzzy_dl_owl2/fuzzydl/feature_function.py +148 -0
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +920 -0
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2_java.py +953 -0
- fuzzy_dl_owl2/fuzzydl/general_concept_inclusion.py +82 -0
- fuzzy_dl_owl2/fuzzydl/individual/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/individual/created_individual.py +219 -0
- fuzzy_dl_owl2/fuzzydl/individual/individual.py +113 -0
- fuzzy_dl_owl2/fuzzydl/individual/representative_individual.py +37 -0
- fuzzy_dl_owl2/fuzzydl/knowledge_base.py +9037 -0
- fuzzy_dl_owl2/fuzzydl/label.py +32 -0
- fuzzy_dl_owl2/fuzzydl/milp/__init__.py +7 -0
- fuzzy_dl_owl2/fuzzydl/milp/expression.py +186 -0
- fuzzy_dl_owl2/fuzzydl/milp/inequation.py +55 -0
- fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +787 -0
- fuzzy_dl_owl2/fuzzydl/milp/show_variables_helper.py +151 -0
- fuzzy_dl_owl2/fuzzydl/milp/solution.py +45 -0
- fuzzy_dl_owl2/fuzzydl/milp/term.py +76 -0
- fuzzy_dl_owl2/fuzzydl/milp/variable.py +89 -0
- fuzzy_dl_owl2/fuzzydl/modifier/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +76 -0
- fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +39 -0
- fuzzy_dl_owl2/fuzzydl/modifier/triangular_modifier.py +76 -0
- fuzzy_dl_owl2/fuzzydl/parser/ParserConstants.py +406 -0
- fuzzy_dl_owl2/fuzzydl/parser/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +2029 -0
- fuzzy_dl_owl2/fuzzydl/parser/ebnf.lark +290 -0
- fuzzy_dl_owl2/fuzzydl/parser/larkx.py +70 -0
- fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +81 -0
- fuzzy_dl_owl2/fuzzydl/query/__init__.py +14 -0
- fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +50 -0
- fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +22 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/__init__.py +4 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +76 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +19 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +88 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +20 -0
- fuzzy_dl_owl2/fuzzydl/query/instance_query.py +19 -0
- fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +32 -0
- fuzzy_dl_owl2/fuzzydl/query/max/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +45 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +31 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +45 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +73 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +64 -0
- fuzzy_dl_owl2/fuzzydl/query/min/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +50 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +31 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +57 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +80 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +65 -0
- fuzzy_dl_owl2/fuzzydl/query/query.py +38 -0
- fuzzy_dl_owl2/fuzzydl/query/related_query.py +15 -0
- fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +37 -0
- fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +20 -0
- fuzzy_dl_owl2/fuzzydl/range_axiom.py +7 -0
- fuzzy_dl_owl2/fuzzydl/relation.py +47 -0
- fuzzy_dl_owl2/fuzzydl/restriction/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +16 -0
- fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +34 -0
- fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +10 -0
- fuzzy_dl_owl2/fuzzydl/util/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/util/config_reader.py +56 -0
- fuzzy_dl_owl2/fuzzydl/util/constants.py +424 -0
- fuzzy_dl_owl2/fuzzydl/util/util.py +73 -0
- fuzzy_dl_owl2/fuzzyowl2/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +1513 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_java.py +1409 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl.py +917 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl_java.py +956 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/__init__.py +0 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/choquet_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/concept_definition.py +14 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_datatype.py +22 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_modifier.py +4 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_nominal_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_property.py +5 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/left_shoulder_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_modifier.py +13 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_property.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/owa_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/property_definition.py +10 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/qowa_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/quasi_sugeno_concept.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/right_shoulder_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/sugeno_concept.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/trapezoidal_function.py +25 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_function.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_modifer.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_max_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_min_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_zero_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/parser/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzyowl2/parser/owl2_parser.py +491 -0
- fuzzy_dl_owl2/fuzzyowl2/util/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzyowl2/util/constants.py +112 -0
- fuzzy_dl_owl2-1.0.0.dist-info/LICENSE +427 -0
- fuzzy_dl_owl2-1.0.0.dist-info/METADATA +299 -0
- fuzzy_dl_owl2-1.0.0.dist-info/RECORD +167 -0
- fuzzy_dl_owl2-1.0.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,953 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import pathlib
|
|
5
|
+
import sys
|
|
6
|
+
import typing
|
|
7
|
+
from functools import partial
|
|
8
|
+
|
|
9
|
+
import jpype
|
|
10
|
+
import jpype.types
|
|
11
|
+
import jpype.imports
|
|
12
|
+
|
|
13
|
+
if jpype.isJVMStarted():
|
|
14
|
+
jpype.shutdownJVM()
|
|
15
|
+
jpype.startJVM(classpath=["./jars/*"])
|
|
16
|
+
|
|
17
|
+
from org.semanticweb.owlapi.apibinding import OWLManager
|
|
18
|
+
from org.semanticweb.owlapi.model import (
|
|
19
|
+
IRI,
|
|
20
|
+
AddAxiom,
|
|
21
|
+
AddOntologyAnnotation,
|
|
22
|
+
OWLAnnotation,
|
|
23
|
+
OWLAnnotationAssertionAxiom,
|
|
24
|
+
OWLAxiom,
|
|
25
|
+
OWLClass,
|
|
26
|
+
OWLClassAssertionAxiom,
|
|
27
|
+
OWLClassExpression,
|
|
28
|
+
OWLDataFactory,
|
|
29
|
+
OWLDataIntersectionOf,
|
|
30
|
+
OWLDataProperty,
|
|
31
|
+
OWLDataPropertyAssertionAxiom,
|
|
32
|
+
OWLDataRange,
|
|
33
|
+
OWLDatatype,
|
|
34
|
+
OWLDatatypeDefinitionAxiom,
|
|
35
|
+
OWLDatatypeRestriction,
|
|
36
|
+
OWLEntity,
|
|
37
|
+
OWLLiteral,
|
|
38
|
+
OWLNamedIndividual,
|
|
39
|
+
OWLObjectProperty,
|
|
40
|
+
OWLObjectPropertyAssertionAxiom,
|
|
41
|
+
OWLOntology,
|
|
42
|
+
OWLOntologyManager,
|
|
43
|
+
OWLSubClassOfAxiom,
|
|
44
|
+
)
|
|
45
|
+
from org.semanticweb.owlapi.vocab import OWLFacet
|
|
46
|
+
from rdflib import RDF, XSD
|
|
47
|
+
|
|
48
|
+
from fuzzy_dl_owl2.fuzzydl.assertion.assertion import Assertion
|
|
49
|
+
from fuzzy_dl_owl2.fuzzydl.concept.all_some_concept import AllSomeConcept
|
|
50
|
+
from fuzzy_dl_owl2.fuzzydl.concept.choquet_integral import ChoquetIntegral
|
|
51
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
52
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.crisp_concrete_concept import (
|
|
53
|
+
CrispConcreteConcept,
|
|
54
|
+
)
|
|
55
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
|
|
56
|
+
FuzzyConcreteConcept,
|
|
57
|
+
)
|
|
58
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.left_concrete_concept import (
|
|
59
|
+
LeftConcreteConcept,
|
|
60
|
+
)
|
|
61
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.right_concrete_concept import (
|
|
62
|
+
RightConcreteConcept,
|
|
63
|
+
)
|
|
64
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.trapezoidal_concrete_concept import (
|
|
65
|
+
TrapezoidalConcreteConcept,
|
|
66
|
+
)
|
|
67
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.triangular_concrete_concept import (
|
|
68
|
+
TriangularConcreteConcept,
|
|
69
|
+
)
|
|
70
|
+
from fuzzy_dl_owl2.fuzzydl.concept.has_value_concept import HasValueConcept
|
|
71
|
+
from fuzzy_dl_owl2.fuzzydl.concept.interface.has_weighted_concepts_interface import (
|
|
72
|
+
HasWeightedConceptsInterface,
|
|
73
|
+
)
|
|
74
|
+
from fuzzy_dl_owl2.fuzzydl.concept.modified.modified_concept import ModifiedConcept
|
|
75
|
+
from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
|
|
76
|
+
from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
|
|
77
|
+
from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
|
|
78
|
+
from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import QsugenoIntegral
|
|
79
|
+
from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
|
|
80
|
+
from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
|
|
81
|
+
from fuzzy_dl_owl2.fuzzydl.concept.value_concept import ValueConcept
|
|
82
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_concept import WeightedConcept
|
|
83
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_max_concept import WeightedMaxConcept
|
|
84
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_min_concept import WeightedMinConcept
|
|
85
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_concept import WeightedSumConcept
|
|
86
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_zero_concept import (
|
|
87
|
+
WeightedSumZeroConcept,
|
|
88
|
+
)
|
|
89
|
+
from fuzzy_dl_owl2.fuzzydl.concept_equivalence import ConceptEquivalence
|
|
90
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
|
|
91
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
|
|
92
|
+
from fuzzy_dl_owl2.fuzzydl.general_concept_inclusion import GeneralConceptInclusion
|
|
93
|
+
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
94
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
|
|
95
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
96
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import TriangularModifier
|
|
97
|
+
from fuzzy_dl_owl2.fuzzydl.parser.dl_parser import DLParser
|
|
98
|
+
from fuzzy_dl_owl2.fuzzydl.primitive_concept_definition import (
|
|
99
|
+
PrimitiveConceptDefinition,
|
|
100
|
+
)
|
|
101
|
+
from fuzzy_dl_owl2.fuzzydl.util import constants
|
|
102
|
+
from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType, ConcreteFeatureType
|
|
103
|
+
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
104
|
+
from fuzzy_dl_owl2.fuzzyowl2.util.constants import FuzzyOWL2Keyword
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class FuzzydlToOwl2:
|
|
108
|
+
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
input_file: str,
|
|
112
|
+
output_file: str,
|
|
113
|
+
base_iri: str = "http://www.semanticweb.org/ontologies/fuzzydl_ontology.owl",
|
|
114
|
+
) -> None:
|
|
115
|
+
self.num_classes: int = 0
|
|
116
|
+
self.kb, _ = DLParser.get_kb(input_file)
|
|
117
|
+
self.ontology_path = base_iri
|
|
118
|
+
self.ontology_iri = IRI.create(base_iri)
|
|
119
|
+
self.manager: OWLOntologyManager = OWLManager.createOWLOntologyManager()
|
|
120
|
+
self.data_factory: OWLDataFactory = self.manager.getOWLDataFactory()
|
|
121
|
+
self.ontology: OWLOntology = self.manager.createOntology(self.ontology_iri)
|
|
122
|
+
self.fuzzyLabel = self.data_factory.getOWLAnnotationProperty(
|
|
123
|
+
IRI.create(f"{self.ontology_iri}#fuzzyLabel")
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
self.concepts: dict[str, OWLClassExpression] = dict()
|
|
127
|
+
self.datatypes: dict[str, OWLDatatype] = dict()
|
|
128
|
+
self.modifiers: dict[str, OWLDatatype] = dict()
|
|
129
|
+
self.input_FDL: str = input_file
|
|
130
|
+
self.output_FOWL: str = os.path.join(constants.RESULTS_PATH, output_file)
|
|
131
|
+
|
|
132
|
+
def iri(self, o: object) -> str:
|
|
133
|
+
"""Convert object to IRI string"""
|
|
134
|
+
return IRI.create(f"{self.ontology_path}#{str(o)}")
|
|
135
|
+
|
|
136
|
+
def get_base(self, c: Concept) -> OWLClassExpression:
|
|
137
|
+
if c.is_atomic():
|
|
138
|
+
return self.get_class(str(c)).asOWLClass()
|
|
139
|
+
return self.get_new_atomic_class(str(c))
|
|
140
|
+
|
|
141
|
+
@typing.overload
|
|
142
|
+
def get_class(self, name: str) -> OWLClassExpression: ...
|
|
143
|
+
|
|
144
|
+
@typing.overload
|
|
145
|
+
def get_class(self, c: Concept) -> OWLClassExpression: ...
|
|
146
|
+
|
|
147
|
+
def get_class(self, *args) -> OWLClassExpression:
|
|
148
|
+
assert len(args) == 1
|
|
149
|
+
if isinstance(args[0], str):
|
|
150
|
+
return self.__get_class_1(*args)
|
|
151
|
+
elif isinstance(args[0], Concept):
|
|
152
|
+
return self.__get_class_2(*args)
|
|
153
|
+
else:
|
|
154
|
+
raise ValueError
|
|
155
|
+
|
|
156
|
+
def __get_class_1(self, name: str) -> OWLClassExpression:
|
|
157
|
+
"""Get or create an OWL class by name"""
|
|
158
|
+
return self.data_factory.getOWLClass(self.iri(name))
|
|
159
|
+
|
|
160
|
+
def __get_class_2(self, c: Concept) -> OWLClassExpression:
|
|
161
|
+
Util.debug(f"Getting class for concept -> {c}")
|
|
162
|
+
c_type: ConceptType = c.type
|
|
163
|
+
if c_type in (ConceptType.ATOMIC, ConceptType.CONCRETE):
|
|
164
|
+
return self.get_class(str(c))
|
|
165
|
+
elif c_type == ConceptType.TOP:
|
|
166
|
+
return self.data_factory.getOWLThing()
|
|
167
|
+
elif c_type == ConceptType.BOTTOM:
|
|
168
|
+
return self.data_factory.getOWLNothing()
|
|
169
|
+
elif c_type in (
|
|
170
|
+
ConceptType.COMPLEMENT,
|
|
171
|
+
ConceptType.NOT_AT_MOST_VALUE,
|
|
172
|
+
ConceptType.NOT_AT_LEAST_VALUE,
|
|
173
|
+
ConceptType.NOT_EXACT_VALUE,
|
|
174
|
+
ConceptType.NOT_WEIGHTED,
|
|
175
|
+
ConceptType.NOT_W_SUM,
|
|
176
|
+
ConceptType.CONCRETE_COMPLEMENT,
|
|
177
|
+
ConceptType.MODIFIED_COMPLEMENT,
|
|
178
|
+
ConceptType.NOT_OWA,
|
|
179
|
+
ConceptType.NOT_QUANTIFIED_OWA,
|
|
180
|
+
ConceptType.NOT_CHOQUET_INTEGRAL,
|
|
181
|
+
ConceptType.NOT_SUGENO_INTEGRAL,
|
|
182
|
+
ConceptType.NOT_QUASI_SUGENO_INTEGRAL,
|
|
183
|
+
ConceptType.NOT_W_MAX,
|
|
184
|
+
ConceptType.NOT_W_MIN,
|
|
185
|
+
ConceptType.NOT_W_SUM_ZERO,
|
|
186
|
+
ConceptType.NOT_SELF,
|
|
187
|
+
ConceptType.NOT_HAS_VALUE,
|
|
188
|
+
):
|
|
189
|
+
return self.data_factory.getOWLObjectComplementOf(self.get_class(-c))
|
|
190
|
+
elif c_type in (
|
|
191
|
+
ConceptType.AND,
|
|
192
|
+
ConceptType.GOEDEL_AND,
|
|
193
|
+
ConceptType.LUKASIEWICZ_AND,
|
|
194
|
+
):
|
|
195
|
+
c: OperatorConcept = typing.cast(OperatorConcept, c)
|
|
196
|
+
return self.data_factory.getOWLObjectIntersectionOf(
|
|
197
|
+
{self.get_class(c1) for c1 in c.concepts}
|
|
198
|
+
)
|
|
199
|
+
elif c_type in (
|
|
200
|
+
ConceptType.OR,
|
|
201
|
+
ConceptType.GOEDEL_OR,
|
|
202
|
+
ConceptType.LUKASIEWICZ_OR,
|
|
203
|
+
):
|
|
204
|
+
c: OperatorConcept = typing.cast(OperatorConcept, c)
|
|
205
|
+
return self.data_factory.getOWLObjectUnionOf(
|
|
206
|
+
{self.get_class(c1) for c1 in c.concepts}
|
|
207
|
+
)
|
|
208
|
+
elif c_type == ConceptType.SOME:
|
|
209
|
+
c: AllSomeConcept = typing.cast(AllSomeConcept, c)
|
|
210
|
+
if str(c.curr_concept) in self.datatypes:
|
|
211
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
212
|
+
self.get_data_property(c.role)
|
|
213
|
+
)
|
|
214
|
+
assert isinstance(dp, OWLDataProperty)
|
|
215
|
+
d: OWLDatatype = self.datatypes.get(str(c.curr_concept))
|
|
216
|
+
return self.data_factory.getOWLDataSomeValuesFrom(dp, d)
|
|
217
|
+
else:
|
|
218
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
219
|
+
self.get_object_property(c.role)
|
|
220
|
+
)
|
|
221
|
+
assert isinstance(op, OWLObjectProperty)
|
|
222
|
+
c2: OWLClassExpression = self.get_class(c.curr_concept)
|
|
223
|
+
return self.data_factory.getOWLObjectSomeValuesFrom(op, c2)
|
|
224
|
+
elif c_type == ConceptType.ALL:
|
|
225
|
+
c: AllSomeConcept = typing.cast(AllSomeConcept, c)
|
|
226
|
+
if str(c.curr_concept) in self.datatypes:
|
|
227
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
228
|
+
self.get_data_property(c.role)
|
|
229
|
+
)
|
|
230
|
+
assert isinstance(dp, OWLDataProperty)
|
|
231
|
+
d: OWLDatatype = self.datatypes.get(str(c.curr_concept))
|
|
232
|
+
return self.data_factory.getOWLDataAllValuesFrom(dp, d)
|
|
233
|
+
else:
|
|
234
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
235
|
+
self.get_object_property(c.role)
|
|
236
|
+
)
|
|
237
|
+
assert isinstance(op, OWLObjectProperty)
|
|
238
|
+
c2: OWLClassExpression = self.get_class(c.curr_concept)
|
|
239
|
+
return self.data_factory.getOWLObjectAllValuesFrom(op, c2)
|
|
240
|
+
elif c_type == ConceptType.MODIFIED:
|
|
241
|
+
c: ModifiedConcept = typing.cast(ModifiedConcept, c)
|
|
242
|
+
if str(c) in self.concepts:
|
|
243
|
+
return self.concepts.get(str(c))
|
|
244
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
245
|
+
c3: OWLClassExpression = self.get_base(c.c1)
|
|
246
|
+
self.concepts[str(c)] = c3
|
|
247
|
+
annotation: str = (
|
|
248
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
249
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{FuzzyOWL2Keyword.MODIFIED.get_str_value()}" {FuzzyOWL2Keyword.MODIFIER.get_str_value()}="{self.modifiers[str(c)]}" {FuzzyOWL2Keyword.BASE.get_str_value()}="{c3}"/>\n',
|
|
250
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>",
|
|
251
|
+
)
|
|
252
|
+
self.add_entity_annotation(annotation, c4)
|
|
253
|
+
return c4
|
|
254
|
+
elif c_type == ConceptType.SELF:
|
|
255
|
+
c: SelfConcept = typing.cast(SelfConcept, c)
|
|
256
|
+
owl_obj_property: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
257
|
+
self.get_object_property(c.role)
|
|
258
|
+
)
|
|
259
|
+
if isinstance(owl_obj_property, OWLObjectProperty):
|
|
260
|
+
return self.data_factory.getOWLObjectHasSelf(owl_obj_property)
|
|
261
|
+
else:
|
|
262
|
+
return self.data_factory.getOWLDataHasSelf(owl_obj_property)
|
|
263
|
+
elif c_type == ConceptType.HAS_VALUE:
|
|
264
|
+
c: HasValueConcept = typing.cast(HasValueConcept, c)
|
|
265
|
+
owl_obj_property: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
266
|
+
self.get_object_property(c.role)
|
|
267
|
+
)
|
|
268
|
+
assert isinstance(owl_obj_property, OWLObjectProperty)
|
|
269
|
+
ind: OWLNamedIndividual = self.get_individual(str(c.value))
|
|
270
|
+
return self.data_factory.getOWLObjectHasValue(owl_obj_property, ind)
|
|
271
|
+
elif c_type in (
|
|
272
|
+
ConceptType.AT_MOST_VALUE,
|
|
273
|
+
ConceptType.AT_LEAST_VALUE,
|
|
274
|
+
ConceptType.EXACT_VALUE,
|
|
275
|
+
):
|
|
276
|
+
c: ValueConcept = typing.cast(ValueConcept, c)
|
|
277
|
+
if isinstance(c.value, int):
|
|
278
|
+
datatype: OWLDatatype = self.data_factory.getIntegerOWLDatatype()
|
|
279
|
+
literal: OWLLiteral = self.data_factory.getOWLLiteral(
|
|
280
|
+
jpype.types.JInt(c.value)
|
|
281
|
+
)
|
|
282
|
+
elif isinstance(c.value, float):
|
|
283
|
+
datatype: OWLDatatype = self.data_factory.getOWLDatatype(
|
|
284
|
+
IRI.create(XSD.decimal)
|
|
285
|
+
)
|
|
286
|
+
literal: OWLLiteral = self.data_factory.getOWLLiteral(
|
|
287
|
+
str(c.value), datatype
|
|
288
|
+
)
|
|
289
|
+
elif isinstance(c.value, str):
|
|
290
|
+
datatype: OWLDatatype = self.data_factory.getRDFPlainLiteral()
|
|
291
|
+
literal: OWLLiteral = self.data_factory.getOWLLiteral(
|
|
292
|
+
jpype.types.JString(c.value)
|
|
293
|
+
)
|
|
294
|
+
if c_type == ConceptType.AT_LEAST_VALUE:
|
|
295
|
+
data_range: OWLDataRange = self.data_factory.getOWLDatatypeRestriction(
|
|
296
|
+
datatype, OWLFacet.MIN_INCLUSIVE, literal
|
|
297
|
+
)
|
|
298
|
+
return self.data_factory.getOWLDataSomeValuesFrom(
|
|
299
|
+
self.get_data_property(c.role), data_range
|
|
300
|
+
)
|
|
301
|
+
elif c_type == ConceptType.AT_MOST_VALUE:
|
|
302
|
+
data_range: OWLDataRange = self.data_factory.getOWLDatatypeRestriction(
|
|
303
|
+
datatype, OWLFacet.MAX_INCLUSIVE, literal
|
|
304
|
+
)
|
|
305
|
+
return self.data_factory.getOWLDataSomeValuesFrom(
|
|
306
|
+
self.get_data_property(c.role), data_range
|
|
307
|
+
)
|
|
308
|
+
else:
|
|
309
|
+
return self.data_factory.getOWLDataHasValue(
|
|
310
|
+
self.get_data_property(c.role), literal
|
|
311
|
+
)
|
|
312
|
+
elif c_type == ConceptType.WEIGHTED:
|
|
313
|
+
c: WeightedConcept = typing.cast(WeightedConcept, c)
|
|
314
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
315
|
+
c3: OWLClassExpression = self.get_base(c.c1)
|
|
316
|
+
annotation: str = (
|
|
317
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
318
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{FuzzyOWL2Keyword.WEIGHTED.get_str_value()}" {FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value()}="{c.weight}" {FuzzyOWL2Keyword.BASE.get_str_value()}="{c3}"/>\n',
|
|
319
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>",
|
|
320
|
+
)
|
|
321
|
+
self.add_entity_annotation(annotation, c3)
|
|
322
|
+
return c4
|
|
323
|
+
elif c_type in (
|
|
324
|
+
ConceptType.W_MAX,
|
|
325
|
+
ConceptType.W_MIN,
|
|
326
|
+
ConceptType.W_SUM,
|
|
327
|
+
ConceptType.W_SUM_ZERO,
|
|
328
|
+
):
|
|
329
|
+
return self.__get_class_weighted_min_max_sum(c)
|
|
330
|
+
elif c_type in (
|
|
331
|
+
ConceptType.OWA,
|
|
332
|
+
ConceptType.QUANTIFIED_OWA,
|
|
333
|
+
ConceptType.CHOQUET_INTEGRAL,
|
|
334
|
+
ConceptType.SUGENO_INTEGRAL,
|
|
335
|
+
ConceptType.QUASI_SUGENO_INTEGRAL,
|
|
336
|
+
):
|
|
337
|
+
return self.__get_class_weighted(c)
|
|
338
|
+
return self.data_factory.getOWLClass(self.iri(str(c)))
|
|
339
|
+
|
|
340
|
+
def __get_class_weighted_min_max_sum(self, c: Concept) -> OWLClassExpression:
|
|
341
|
+
type_dict: dict[ConceptType, str] = {
|
|
342
|
+
ConceptType.W_MAX: FuzzyOWL2Keyword.WEIGHTED_MAXIMUM.get_str_value(),
|
|
343
|
+
ConceptType.W_MIN: FuzzyOWL2Keyword.WEIGHTED_MINIMUM.get_str_value(),
|
|
344
|
+
ConceptType.W_SUM: FuzzyOWL2Keyword.WEIGHTED_SUM.get_str_value(),
|
|
345
|
+
ConceptType.W_SUM_ZERO: FuzzyOWL2Keyword.WEIGHTED_SUMZERO.get_str_value(),
|
|
346
|
+
}
|
|
347
|
+
type_cast: dict[ConceptType, typing.Callable] = {
|
|
348
|
+
ConceptType.W_MAX: partial(typing.cast, WeightedMaxConcept),
|
|
349
|
+
ConceptType.W_MIN: partial(typing.cast, WeightedMinConcept),
|
|
350
|
+
ConceptType.W_SUM: partial(typing.cast, WeightedSumConcept),
|
|
351
|
+
ConceptType.W_SUM_ZERO: partial(typing.cast, WeightedSumZeroConcept),
|
|
352
|
+
}
|
|
353
|
+
if c.type not in type_dict:
|
|
354
|
+
return None
|
|
355
|
+
curr_concept: HasWeightedConceptsInterface = type_cast[c.type](c)
|
|
356
|
+
c3: OWLClassExpression = self.get_new_atomic_class(str(curr_concept))
|
|
357
|
+
|
|
358
|
+
annotation: str = (
|
|
359
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
360
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{type_dict[c.type]}">\n ',
|
|
361
|
+
)
|
|
362
|
+
for i in range(len(curr_concept.concepts)):
|
|
363
|
+
c5: OWLClassExpression = self.get_base(curr_concept.concepts[i])
|
|
364
|
+
annotation += f'\t\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{FuzzyOWL2Keyword.WEIGHTED.get_str_value()}" {FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value()}="{curr_concept.weights[i]}" {FuzzyOWL2Keyword.BASE.get_str_value()}="{c5}" />\n'
|
|
365
|
+
annotation: str = (
|
|
366
|
+
f"\t</{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} >\n</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} >"
|
|
367
|
+
)
|
|
368
|
+
self.add_entity_annotation(annotation, c3)
|
|
369
|
+
return c3
|
|
370
|
+
|
|
371
|
+
def __get_class_weighted(self, c: Concept) -> OWLClassExpression:
|
|
372
|
+
type_dict: dict[ConceptType, str] = {
|
|
373
|
+
ConceptType.OWA: FuzzyOWL2Keyword.OWA.get_str_value(),
|
|
374
|
+
ConceptType.QUANTIFIED_OWA: FuzzyOWL2Keyword.Q_OWA.get_str_value(),
|
|
375
|
+
ConceptType.CHOQUET_INTEGRAL: FuzzyOWL2Keyword.CHOQUET.get_str_value(),
|
|
376
|
+
ConceptType.SUGENO_INTEGRAL: FuzzyOWL2Keyword.SUGENO.get_str_value(),
|
|
377
|
+
ConceptType.QUASI_SUGENO_INTEGRAL: FuzzyOWL2Keyword.QUASI_SUGENO.get_str_value(),
|
|
378
|
+
}
|
|
379
|
+
type_cast: dict[ConceptType, typing.Callable] = {
|
|
380
|
+
ConceptType.OWA: partial(typing.cast, OwaConcept),
|
|
381
|
+
ConceptType.QUANTIFIED_OWA: partial(typing.cast, QowaConcept),
|
|
382
|
+
ConceptType.CHOQUET_INTEGRAL: partial(typing.cast, ChoquetIntegral),
|
|
383
|
+
ConceptType.SUGENO_INTEGRAL: partial(typing.cast, SugenoIntegral),
|
|
384
|
+
ConceptType.QUASI_SUGENO_INTEGRAL: partial(typing.cast, QsugenoIntegral),
|
|
385
|
+
}
|
|
386
|
+
if c.type not in type_dict:
|
|
387
|
+
return None
|
|
388
|
+
curr_concept: HasWeightedConceptsInterface = type_cast[c.type](c)
|
|
389
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
390
|
+
annotation: str = (
|
|
391
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
392
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{type_dict[c.type]}">\n',
|
|
393
|
+
f"\t\t<{FuzzyOWL2Keyword.WEIGHTS.get_tag_name()}>\n",
|
|
394
|
+
)
|
|
395
|
+
for d in curr_concept.weights:
|
|
396
|
+
annotation += f"\t\t\t<{FuzzyOWL2Keyword.WEIGHT.get_tag_name()}>{d}</{FuzzyOWL2Keyword.WEIGHT.get_tag_name()}>\n"
|
|
397
|
+
annotation += f"\t\t</{FuzzyOWL2Keyword.WEIGHTS.get_tag_name()}>\n\t\t<{FuzzyOWL2Keyword.CONCEPT_NAMES.get_tag_name()}>\n"
|
|
398
|
+
for ci in curr_concept.concepts:
|
|
399
|
+
c5: OWLClassExpression = self.get_base(ci)
|
|
400
|
+
annotation += f"\t\t\t<{FuzzyOWL2Keyword.NAME.get_tag_name()}>{c5}</{FuzzyOWL2Keyword.NAME.get_tag_name()}>\n"
|
|
401
|
+
annotation += f"\t\t</{FuzzyOWL2Keyword.CONCEPT_NAMES.get_tag_name()}>\n\t</{FuzzyOWL2Keyword.CONCEPT.get_tag_name()}>\n</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
402
|
+
self.add_entity_annotation(annotation, c4)
|
|
403
|
+
return c4
|
|
404
|
+
|
|
405
|
+
def get_new_atomic_class(self, name: str) -> OWLClassExpression:
|
|
406
|
+
"""Get or create a new atomic class"""
|
|
407
|
+
Util.debug(f"Getting new atomic concept -> {name}")
|
|
408
|
+
c = self.concepts.get(name)
|
|
409
|
+
if c is not None:
|
|
410
|
+
return c
|
|
411
|
+
|
|
412
|
+
self.num_classes += 1
|
|
413
|
+
Util.debug(f"Creating new atomic concept -> {name}")
|
|
414
|
+
c2: OWLClass = self.data_factory.getOWLClass(
|
|
415
|
+
self.iri(f"class__{self.num_classes}")
|
|
416
|
+
)
|
|
417
|
+
self.concepts[name] = c2
|
|
418
|
+
return c2
|
|
419
|
+
|
|
420
|
+
def exist_object_property(self, role: str) -> bool:
|
|
421
|
+
return any(
|
|
422
|
+
prop.getIRI().equals(self.iri(role))
|
|
423
|
+
for prop in self.ontology.getObjectPropertiesInSignature()
|
|
424
|
+
)
|
|
425
|
+
|
|
426
|
+
def exist_data_property(self, role: str) -> bool:
|
|
427
|
+
return any(
|
|
428
|
+
prop.getIRI().equals(self.iri(role))
|
|
429
|
+
for prop in self.ontology.getDataPropertiesInSignature()
|
|
430
|
+
)
|
|
431
|
+
|
|
432
|
+
def get_object_property(
|
|
433
|
+
self, role: str
|
|
434
|
+
) -> typing.Union[OWLDataProperty, OWLObjectProperty]:
|
|
435
|
+
"""Get or create an object property"""
|
|
436
|
+
Util.debug(f"Getting object property -> {role}")
|
|
437
|
+
if self.exist_data_property(role):
|
|
438
|
+
return self.get_data_property(role)
|
|
439
|
+
return self.data_factory.getOWLObjectProperty(self.iri(role))
|
|
440
|
+
|
|
441
|
+
def get_data_property(
|
|
442
|
+
self, role: str
|
|
443
|
+
) -> typing.Union[OWLDataProperty, OWLObjectProperty]:
|
|
444
|
+
"""Get or create a data property"""
|
|
445
|
+
Util.debug(f"Getting data property -> {role}")
|
|
446
|
+
if self.exist_object_property(role):
|
|
447
|
+
return self.get_object_property(role)
|
|
448
|
+
return self.data_factory.getOWLDataProperty(self.iri(role))
|
|
449
|
+
|
|
450
|
+
def get_individual(self, name: str) -> OWLNamedIndividual:
|
|
451
|
+
"""Get or create a named individual"""
|
|
452
|
+
Util.debug(f"Getting individual -> {name}")
|
|
453
|
+
return self.data_factory.getOWLNamedIndividual(self.iri(f"{name}_Individual"))
|
|
454
|
+
|
|
455
|
+
def add_ontology_annotation(self, annotation: str) -> None:
|
|
456
|
+
"""Add annotation to the ontology"""
|
|
457
|
+
Util.debug(f"Adding annotation to ontology -> {annotation}")
|
|
458
|
+
comment: OWLAnnotation = self.data_factory.getOWLAnnotation(
|
|
459
|
+
self.fuzzyLabel,
|
|
460
|
+
self.data_factory.getOWLLiteral(
|
|
461
|
+
annotation,
|
|
462
|
+
self.data_factory.getOWLDatatype(IRI.create(str(RDF.PlainLiteral))),
|
|
463
|
+
),
|
|
464
|
+
)
|
|
465
|
+
ann: AddOntologyAnnotation = AddOntologyAnnotation(self.ontology, comment)
|
|
466
|
+
self.manager.applyChange(ann)
|
|
467
|
+
|
|
468
|
+
def add_entity_annotation(self, annotation: str, entity: OWLEntity) -> None:
|
|
469
|
+
"""Add annotation to an entity"""
|
|
470
|
+
# define_datatype_in_ontology(entity, self.iri(entity), self.ontology)
|
|
471
|
+
Util.debug(f"Adding annotation to entity {entity} -> {annotation}")
|
|
472
|
+
owl_annotation: OWLAnnotation = self.data_factory.getOWLAnnotation(
|
|
473
|
+
self.fuzzyLabel,
|
|
474
|
+
self.data_factory.getOWLLiteral(
|
|
475
|
+
annotation,
|
|
476
|
+
self.data_factory.getOWLDatatype(IRI.create(str(RDF.PlainLiteral))),
|
|
477
|
+
),
|
|
478
|
+
)
|
|
479
|
+
axiom: OWLAnnotationAssertionAxiom = (
|
|
480
|
+
self.data_factory.getOWLAnnotationAssertionAxiom(
|
|
481
|
+
entity.getIRI(), owl_annotation
|
|
482
|
+
)
|
|
483
|
+
)
|
|
484
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
485
|
+
|
|
486
|
+
def get_annotations_for_axiom(
|
|
487
|
+
self, value: typing.Union[float, DegreeNumeric]
|
|
488
|
+
) -> set[OWLAnnotation]:
|
|
489
|
+
"""Get annotations for an axiom with degree"""
|
|
490
|
+
if isinstance(value, float):
|
|
491
|
+
n = value
|
|
492
|
+
elif isinstance(value, DegreeNumeric): # Degree object
|
|
493
|
+
n = value.get_numerical_value()
|
|
494
|
+
|
|
495
|
+
annotation_text: str = (
|
|
496
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.AXIOM.get_str_value()}">\n'
|
|
497
|
+
f'\t<{FuzzyOWL2Keyword.DEGREE_DEF.get_tag_name()} {FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value()}="{n}"/>\n'
|
|
498
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
499
|
+
)
|
|
500
|
+
annotation: OWLAnnotation = self.data_factory.getOWLAnnotation(
|
|
501
|
+
self.fuzzyLabel,
|
|
502
|
+
self.data_factory.getOWLLiteral(
|
|
503
|
+
annotation_text,
|
|
504
|
+
self.data_factory.getOWLDatatype(IRI.create(str(RDF.PlainLiteral))),
|
|
505
|
+
),
|
|
506
|
+
)
|
|
507
|
+
return set([annotation])
|
|
508
|
+
|
|
509
|
+
def annotate_gci(self, gci: GeneralConceptInclusion) -> None:
|
|
510
|
+
c1: OWLClassExpression = self.get_class(gci.get_subsumed())
|
|
511
|
+
c2: OWLClassExpression = self.get_class(gci.get_subsumer())
|
|
512
|
+
deg: Degree = gci.get_degree()
|
|
513
|
+
Util.debug(f"Annotate GCI -> {c1} - {c2} - {deg}")
|
|
514
|
+
if deg.is_number_not_one():
|
|
515
|
+
new_annotations: set[OWLAnnotation] = self.get_annotations_for_axiom(deg)
|
|
516
|
+
axiom: OWLSubClassOfAxiom = self.data_factory.getOWLSubClassOfAxiom(
|
|
517
|
+
c1, c2, new_annotations
|
|
518
|
+
)
|
|
519
|
+
else:
|
|
520
|
+
axiom: OWLSubClassOfAxiom = self.data_factory.getOWLSubClassOfAxiom(c1, c2)
|
|
521
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
522
|
+
|
|
523
|
+
def annotate_pcd(
|
|
524
|
+
self, c1: OWLClassExpression, pcd: PrimitiveConceptDefinition
|
|
525
|
+
) -> None:
|
|
526
|
+
c2: OWLClassExpression = self.get_class(pcd.get_definition())
|
|
527
|
+
n: float = pcd.get_degree()
|
|
528
|
+
Util.debug(f"Annotate PCD -> {c1} - {c2} - {n}")
|
|
529
|
+
if n != 1.0:
|
|
530
|
+
new_annotations: set[OWLAnnotation] = self.get_annotations_for_axiom(n)
|
|
531
|
+
axiom: OWLSubClassOfAxiom = self.data_factory.getOWLSubClassOfAxiom(
|
|
532
|
+
c1, c2, new_annotations
|
|
533
|
+
)
|
|
534
|
+
else:
|
|
535
|
+
axiom: OWLSubClassOfAxiom = self.data_factory.getOWLSubClassOfAxiom(c1, c2)
|
|
536
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
537
|
+
|
|
538
|
+
def run(self) -> None:
|
|
539
|
+
"""Execute the conversion process"""
|
|
540
|
+
# Set fuzzy logic type
|
|
541
|
+
logic = str(constants.KNOWLEDGE_BASE_SEMANTICS)
|
|
542
|
+
|
|
543
|
+
if logic:
|
|
544
|
+
annotation: str = (
|
|
545
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.ONTOLOGY.get_str_value()}">\n'
|
|
546
|
+
f'\t<{FuzzyOWL2Keyword.FUZZY_LOGIC.get_tag_name()} {FuzzyOWL2Keyword.LOGIC.get_str_value()}="{logic}" />\n'
|
|
547
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
548
|
+
)
|
|
549
|
+
self.add_ontology_annotation(annotation)
|
|
550
|
+
|
|
551
|
+
# Process concrete concepts
|
|
552
|
+
for c in self.kb.concrete_concepts.values():
|
|
553
|
+
self._process_concrete_concept(c)
|
|
554
|
+
|
|
555
|
+
# Process modifiers
|
|
556
|
+
for mod in self.kb.modifiers.values():
|
|
557
|
+
self._process_modifier(mod)
|
|
558
|
+
|
|
559
|
+
# Process assertions
|
|
560
|
+
for ass in self.kb.assertions:
|
|
561
|
+
self._process_assertion(ass)
|
|
562
|
+
|
|
563
|
+
# Process individuals
|
|
564
|
+
for ind in self.kb.individuals.values():
|
|
565
|
+
self._process_individual(ind)
|
|
566
|
+
|
|
567
|
+
for a in self.kb.axioms_A_equiv_C:
|
|
568
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
569
|
+
for c in self.kb.axioms_A_equiv_C[a]:
|
|
570
|
+
c2: OWLClassExpression = self.get_class(c)
|
|
571
|
+
Util.debug(f"Process axioms_A_equiv_C -> {c1} - {c2}")
|
|
572
|
+
axiom: OWLAxiom = self.data_factory.getOWLEquivalentClassesAxiom(
|
|
573
|
+
jpype.types.JArray(OWLClassExpression)([c1, c2])
|
|
574
|
+
)
|
|
575
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
576
|
+
|
|
577
|
+
for a in self.kb.axioms_A_is_a_B:
|
|
578
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
579
|
+
for pcd in self.kb.axioms_A_is_a_B[a]:
|
|
580
|
+
Util.debug(f"Process axioms_A_is_a_B -> {c1} - {pcd}")
|
|
581
|
+
self.annotate_pcd(c1, pcd)
|
|
582
|
+
|
|
583
|
+
for a in self.kb.axioms_A_is_a_C:
|
|
584
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
585
|
+
for pcd in self.kb.axioms_A_is_a_C[a]:
|
|
586
|
+
Util.debug(f"Process axioms_A_is_a_C -> {c1} - {pcd}")
|
|
587
|
+
self.annotate_pcd(c1, pcd)
|
|
588
|
+
|
|
589
|
+
for gcis in self.kb.axioms_C_is_a_D.values():
|
|
590
|
+
for gci in gcis:
|
|
591
|
+
Util.debug(f"Process axioms_C_is_a_D -> {gci}")
|
|
592
|
+
self.annotate_gci(gci)
|
|
593
|
+
|
|
594
|
+
for gcis in self.kb.axioms_C_is_a_A.values():
|
|
595
|
+
for gci in gcis:
|
|
596
|
+
Util.debug(f"Process axioms_C_is_a_A -> {gci}")
|
|
597
|
+
self.annotate_gci(gci)
|
|
598
|
+
|
|
599
|
+
for ce in self.kb.axioms_C_equiv_D:
|
|
600
|
+
ce: ConceptEquivalence = typing.cast(ConceptEquivalence, ce)
|
|
601
|
+
Util.debug(f"Process axioms_C_equiv_D -> {ce}")
|
|
602
|
+
c1: OWLClassExpression = self.get_class(ce.get_c1())
|
|
603
|
+
c2: OWLClassExpression = self.get_class(ce.get_c2())
|
|
604
|
+
axiom: OWLAxiom = self.data_factory.getOWLEquivalentClassesAxiom(c1, c2)
|
|
605
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
606
|
+
|
|
607
|
+
for a in self.kb.t_disjoints:
|
|
608
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
609
|
+
for disj_C in self.kb.t_disjoints[a]:
|
|
610
|
+
Util.debug(f"Process t_dis -> {c1} - {disj_C}")
|
|
611
|
+
if a >= disj_C:
|
|
612
|
+
continue
|
|
613
|
+
c2: OWLClassExpression = self.get_class(disj_C)
|
|
614
|
+
axiom: OWLAxiom = self.data_factory.getOWLDisjointClassesAxiom(c1, c2)
|
|
615
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
616
|
+
|
|
617
|
+
for r in self.kb.domain_restrictions:
|
|
618
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
619
|
+
self.get_object_property(r)
|
|
620
|
+
)
|
|
621
|
+
for c in self.kb.domain_restrictions[r]:
|
|
622
|
+
Util.debug(f"Process domain restriction -> {c}")
|
|
623
|
+
cl: OWLClassExpression = self.get_class(c)
|
|
624
|
+
if isinstance(op, OWLObjectProperty):
|
|
625
|
+
axiom: OWLAxiom = self.data_factory.getOWLObjectPropertyDomainAxiom(
|
|
626
|
+
op, cl
|
|
627
|
+
)
|
|
628
|
+
else:
|
|
629
|
+
axiom: OWLAxiom = self.data_factory.getOWLDataPropertyDomainAxiom(
|
|
630
|
+
op, cl
|
|
631
|
+
)
|
|
632
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
633
|
+
|
|
634
|
+
for r in self.kb.range_restrictions:
|
|
635
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
636
|
+
self.get_object_property(r)
|
|
637
|
+
)
|
|
638
|
+
for c in self.kb.range_restrictions[r]:
|
|
639
|
+
Util.debug(f"Process range restriction -> {c}")
|
|
640
|
+
cl: OWLClassExpression = self.get_class(c)
|
|
641
|
+
if isinstance(op, OWLObjectProperty):
|
|
642
|
+
axiom: OWLAxiom = self.data_factory.getOWLObjectPropertyRangeAxiom(
|
|
643
|
+
op, cl
|
|
644
|
+
)
|
|
645
|
+
else:
|
|
646
|
+
axiom: OWLAxiom = self.data_factory.getOWLDataPropertyRangeAxiom(
|
|
647
|
+
op, cl
|
|
648
|
+
)
|
|
649
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
650
|
+
|
|
651
|
+
for r in self.kb.reflexive_roles:
|
|
652
|
+
Util.debug(f"Process reflexive role -> {r}")
|
|
653
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
654
|
+
self.get_object_property(r)
|
|
655
|
+
)
|
|
656
|
+
if isinstance(op, OWLObjectProperty):
|
|
657
|
+
axiom: OWLAxiom = self.data_factory.getOWLReflexiveObjectPropertyAxiom(
|
|
658
|
+
op
|
|
659
|
+
)
|
|
660
|
+
else:
|
|
661
|
+
axiom: OWLAxiom = self.data_factory.getOWLReflexiveDataPropertyAxiom(op)
|
|
662
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
663
|
+
|
|
664
|
+
for r in self.kb.symmetric_roles:
|
|
665
|
+
Util.debug(f"Process symmetric role -> {r}")
|
|
666
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
667
|
+
self.get_object_property(r)
|
|
668
|
+
)
|
|
669
|
+
if isinstance(op, OWLObjectProperty):
|
|
670
|
+
axiom: OWLAxiom = self.data_factory.getOWLSymmetricObjectPropertyAxiom(
|
|
671
|
+
op
|
|
672
|
+
)
|
|
673
|
+
else:
|
|
674
|
+
axiom: OWLAxiom = self.data_factory.getOWLSymmetricDataPropertyAxiom(op)
|
|
675
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
676
|
+
|
|
677
|
+
for r in self.kb.transitive_roles:
|
|
678
|
+
Util.debug(f"Process transitive role -> {r}")
|
|
679
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
680
|
+
self.get_object_property(r)
|
|
681
|
+
)
|
|
682
|
+
if isinstance(op, OWLObjectProperty):
|
|
683
|
+
axiom: OWLAxiom = self.data_factory.getOWLTransitiveObjectPropertyAxiom(
|
|
684
|
+
op
|
|
685
|
+
)
|
|
686
|
+
else:
|
|
687
|
+
axiom: OWLAxiom = self.data_factory.getOWLTransitiveDataPropertyAxiom(
|
|
688
|
+
op
|
|
689
|
+
)
|
|
690
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
691
|
+
|
|
692
|
+
for r, r_set in self.kb.inverse_roles.items():
|
|
693
|
+
Util.debug(f"Process inverse role -> inv_role = {r}")
|
|
694
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
695
|
+
self.get_object_property(r)
|
|
696
|
+
)
|
|
697
|
+
for s in r_set:
|
|
698
|
+
Util.debug(f"Process inverse role -> role = {s}")
|
|
699
|
+
op2: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
700
|
+
self.get_object_property(s)
|
|
701
|
+
)
|
|
702
|
+
if isinstance(op, OWLObjectProperty) and isinstance(
|
|
703
|
+
op2, OWLObjectProperty
|
|
704
|
+
):
|
|
705
|
+
axiom: OWLAxiom = (
|
|
706
|
+
self.data_factory.getOWLInverseObjectPropertiesAxiom(op, op2)
|
|
707
|
+
)
|
|
708
|
+
elif isinstance(op, OWLDataProperty) and isinstance(
|
|
709
|
+
op2, OWLDataProperty
|
|
710
|
+
):
|
|
711
|
+
axiom: OWLAxiom = (
|
|
712
|
+
self.data_factory.getOWLInverseDataPropertiesAxiom(op, op2)
|
|
713
|
+
)
|
|
714
|
+
else:
|
|
715
|
+
raise ValueError
|
|
716
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
717
|
+
|
|
718
|
+
for r in self.kb.roles_with_parents:
|
|
719
|
+
Util.debug(f"Process role with parents -> role = {r}")
|
|
720
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
721
|
+
self.get_object_property(r)
|
|
722
|
+
)
|
|
723
|
+
par: dict[str, float] = self.kb.roles_with_parents.get(r, dict())
|
|
724
|
+
for s in par:
|
|
725
|
+
Util.debug(f"Process role with parents -> parent = {s}")
|
|
726
|
+
op2: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
727
|
+
self.get_object_property(s)
|
|
728
|
+
)
|
|
729
|
+
if isinstance(op, OWLObjectProperty) and isinstance(
|
|
730
|
+
op2, OWLObjectProperty
|
|
731
|
+
):
|
|
732
|
+
axiom: OWLAxiom = self.data_factory.getOWLSubObjectPropertyOfAxiom(
|
|
733
|
+
op, op2
|
|
734
|
+
)
|
|
735
|
+
elif isinstance(op, OWLDataProperty) and isinstance(
|
|
736
|
+
op2, OWLDataProperty
|
|
737
|
+
):
|
|
738
|
+
axiom: OWLAxiom = self.data_factory.getOWLSubDataPropertyOfAxiom(
|
|
739
|
+
op, op2
|
|
740
|
+
)
|
|
741
|
+
else:
|
|
742
|
+
raise ValueError
|
|
743
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
744
|
+
|
|
745
|
+
for r in self.kb.functional_roles:
|
|
746
|
+
Util.debug(f"Process functional role -> {r}")
|
|
747
|
+
if r in self.kb.concrete_features:
|
|
748
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
749
|
+
self.get_data_property(r)
|
|
750
|
+
)
|
|
751
|
+
if isinstance(dp, OWLDataProperty):
|
|
752
|
+
axiom: OWLAxiom = (
|
|
753
|
+
self.data_factory.getOWLFunctionalDataPropertyAxiom(dp)
|
|
754
|
+
)
|
|
755
|
+
else:
|
|
756
|
+
axiom: OWLAxiom = (
|
|
757
|
+
self.data_factory.getOWLFunctionalObjectPropertyAxiom(dp)
|
|
758
|
+
)
|
|
759
|
+
else:
|
|
760
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
761
|
+
self.get_object_property(r)
|
|
762
|
+
)
|
|
763
|
+
if isinstance(op, OWLObjectProperty):
|
|
764
|
+
axiom: OWLAxiom = (
|
|
765
|
+
self.data_factory.getOWLFunctionalObjectPropertyAxiom(op)
|
|
766
|
+
)
|
|
767
|
+
else:
|
|
768
|
+
axiom: OWLAxiom = (
|
|
769
|
+
self.data_factory.getOWLFunctionalDataPropertyAxiom(op)
|
|
770
|
+
)
|
|
771
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
772
|
+
|
|
773
|
+
for cf_name, cf in self.kb.concrete_features.items():
|
|
774
|
+
if cf is None:
|
|
775
|
+
continue
|
|
776
|
+
Util.debug(f"Process concrete feature {cf_name} -> {cf}")
|
|
777
|
+
cf_type: ConcreteFeatureType = cf.get_type()
|
|
778
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
779
|
+
self.get_data_property(cf_name)
|
|
780
|
+
)
|
|
781
|
+
if cf_type == ConcreteFeatureType.BOOLEAN:
|
|
782
|
+
dt: OWLDatatype = self.data_factory.getBooleanOWLDatatype()
|
|
783
|
+
elif cf_type == ConcreteFeatureType.INTEGER:
|
|
784
|
+
dt: OWLDatatype = self.data_factory.getIntegerOWLDatatype()
|
|
785
|
+
elif cf_type == ConcreteFeatureType.REAL:
|
|
786
|
+
dt: OWLDatatype = self.data_factory.getOWLDatatype(
|
|
787
|
+
IRI.create(XSD.decimal)
|
|
788
|
+
)
|
|
789
|
+
elif cf_type == ConcreteFeatureType.STRING:
|
|
790
|
+
dt: OWLDatatype = self.data_factory.getRDFPlainLiteral()
|
|
791
|
+
# Util.warning(
|
|
792
|
+
# "To Implement: String Datatype Property Range conversion"
|
|
793
|
+
# )
|
|
794
|
+
if isinstance(dp, OWLDataProperty):
|
|
795
|
+
axiom: OWLAxiom = self.data_factory.getOWLDataPropertyRangeAxiom(dp, dt)
|
|
796
|
+
else:
|
|
797
|
+
axiom: OWLAxiom = self.data_factory.getOWLObjectPropertyRangeAxiom(
|
|
798
|
+
dp, dt
|
|
799
|
+
)
|
|
800
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
801
|
+
|
|
802
|
+
# Save ontology
|
|
803
|
+
try:
|
|
804
|
+
self.manager.saveOntology(
|
|
805
|
+
self.ontology,
|
|
806
|
+
IRI.create(pathlib.Path(os.path.abspath(self.output_FOWL)).as_uri()),
|
|
807
|
+
)
|
|
808
|
+
except Exception as ex:
|
|
809
|
+
Util.error(f"Error saving ontology: {ex}", file=sys.stderr)
|
|
810
|
+
raise
|
|
811
|
+
|
|
812
|
+
def _process_concrete_concept(self, c: FuzzyConcreteConcept) -> None:
|
|
813
|
+
"""Process a concrete concept"""
|
|
814
|
+
Util.debug(f"Process concrete concept -> {c}")
|
|
815
|
+
current_datatype: OWLDatatype = self.data_factory.getOWLDatatype(self.iri(c))
|
|
816
|
+
self.datatypes[str(c)] = current_datatype
|
|
817
|
+
|
|
818
|
+
specific: str = self._get_concrete_concept_specifics(c)
|
|
819
|
+
|
|
820
|
+
int_datatype: OWLDatatype = self.data_factory.getIntegerOWLDatatype()
|
|
821
|
+
decimal: OWLDatatype = self.data_factory.getOWLDatatype(IRI.create(XSD.decimal))
|
|
822
|
+
greater_than: OWLDatatypeRestriction = (
|
|
823
|
+
self.data_factory.getOWLDatatypeRestriction(
|
|
824
|
+
int_datatype,
|
|
825
|
+
OWLFacet.MIN_INCLUSIVE,
|
|
826
|
+
self.data_factory.getOWLLiteral(str(c.k1), decimal),
|
|
827
|
+
)
|
|
828
|
+
)
|
|
829
|
+
less_than: OWLDatatypeRestriction = self.data_factory.getOWLDatatypeRestriction(
|
|
830
|
+
int_datatype,
|
|
831
|
+
OWLFacet.MAX_INCLUSIVE,
|
|
832
|
+
self.data_factory.getOWLLiteral(str(c.k2), decimal),
|
|
833
|
+
)
|
|
834
|
+
unit_interval: OWLDataIntersectionOf = (
|
|
835
|
+
self.data_factory.getOWLDataIntersectionOf(greater_than, less_than)
|
|
836
|
+
)
|
|
837
|
+
definition: OWLDatatypeDefinitionAxiom = (
|
|
838
|
+
self.data_factory.getOWLDatatypeDefinitionAxiom(
|
|
839
|
+
current_datatype, unit_interval
|
|
840
|
+
)
|
|
841
|
+
)
|
|
842
|
+
self.manager.applyChange(AddAxiom(self.ontology, definition))
|
|
843
|
+
|
|
844
|
+
annotation: str = (
|
|
845
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.DATATYPE.get_str_value()}">\n'
|
|
846
|
+
f'\t<{FuzzyOWL2Keyword.DATATYPE.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{specific}"/>\n'
|
|
847
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
848
|
+
)
|
|
849
|
+
self.add_entity_annotation(annotation, current_datatype)
|
|
850
|
+
|
|
851
|
+
def _get_concrete_concept_specifics(self, c: FuzzyConcreteConcept) -> str:
|
|
852
|
+
"""Get concrete concept specific parameters"""
|
|
853
|
+
if isinstance(c, CrispConcreteConcept):
|
|
854
|
+
return f'{FuzzyOWL2Keyword.CRISP.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
855
|
+
elif isinstance(c, LeftConcreteConcept):
|
|
856
|
+
return f'{FuzzyOWL2Keyword.LEFT_SHOULDER.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
857
|
+
elif isinstance(c, RightConcreteConcept):
|
|
858
|
+
return f'{FuzzyOWL2Keyword.RIGHT_SHOULDER.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
859
|
+
elif isinstance(c, TriangularConcreteConcept):
|
|
860
|
+
return f'{FuzzyOWL2Keyword.TRIANGULAR.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}" {FuzzyOWL2Keyword.C.get_str_value()}="{c.c}'
|
|
861
|
+
elif isinstance(c, TrapezoidalConcreteConcept):
|
|
862
|
+
return f'{FuzzyOWL2Keyword.TRAPEZOIDAL.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}" {FuzzyOWL2Keyword.C.get_str_value()}="{c.c}" {FuzzyOWL2Keyword.D.get_str_value()}="{c.d}'
|
|
863
|
+
return ""
|
|
864
|
+
|
|
865
|
+
def _process_modifier(self, mod: Modifier) -> None:
|
|
866
|
+
"""Process a modifier"""
|
|
867
|
+
Util.debug(f"Process modifier -> {mod}")
|
|
868
|
+
if isinstance(mod, LinearModifier):
|
|
869
|
+
annotation: str = (
|
|
870
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.MODIFIER.get_str_value()}">\n'
|
|
871
|
+
f'\t<{FuzzyOWL2Keyword.MODIFIER.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{FuzzyOWL2Keyword.LINEAR.get_str_value()}" {FuzzyOWL2Keyword.C.get_str_value()}="{mod.c}"/>\n'
|
|
872
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
873
|
+
)
|
|
874
|
+
elif isinstance(mod, TriangularModifier):
|
|
875
|
+
annotation: str = (
|
|
876
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.MODIFIER.get_str_value()}">\n'
|
|
877
|
+
f'\t<{FuzzyOWL2Keyword.MODIFIER.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{FuzzyOWL2Keyword.TRIANGULAR.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{mod.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{mod.b}" {FuzzyOWL2Keyword.C.get_str_value()}="{mod.c}"/>\n'
|
|
878
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
879
|
+
)
|
|
880
|
+
else:
|
|
881
|
+
raise ValueError
|
|
882
|
+
|
|
883
|
+
current_datatype: OWLDatatype = self.data_factory.getOWLDatatype(self.iri(mod))
|
|
884
|
+
self.modifiers[str(mod)] = current_datatype
|
|
885
|
+
self.add_entity_annotation(annotation, current_datatype)
|
|
886
|
+
|
|
887
|
+
def _process_assertion(self, ass: Assertion) -> None:
|
|
888
|
+
Util.debug(f"Process assertion -> {ass}")
|
|
889
|
+
i: OWLNamedIndividual = self.get_individual(str(ass.get_individual()))
|
|
890
|
+
c: OWLClassExpression = self.get_class(ass.get_concept())
|
|
891
|
+
deg: Degree = ass.get_lower_limit()
|
|
892
|
+
if deg.is_number_not_one():
|
|
893
|
+
new_ann: set[OWLAnnotation] = self.get_annotations_for_axiom(deg)
|
|
894
|
+
axiom: OWLClassAssertionAxiom = self.data_factory.getOWLClassAssertionAxiom(
|
|
895
|
+
c, i, new_ann
|
|
896
|
+
)
|
|
897
|
+
else:
|
|
898
|
+
axiom: OWLClassAssertionAxiom = self.data_factory.getOWLClassAssertionAxiom(
|
|
899
|
+
c, i
|
|
900
|
+
)
|
|
901
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
902
|
+
|
|
903
|
+
def _process_individual(self, ind: Individual) -> None:
|
|
904
|
+
Util.debug(f"Process individual -> {ind}")
|
|
905
|
+
i: OWLClassExpression = self.get_individual(str(ind))
|
|
906
|
+
for a in ind.role_relations.values():
|
|
907
|
+
for rel in a:
|
|
908
|
+
r: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
909
|
+
self.get_object_property(rel.get_role_name())
|
|
910
|
+
) # Retrieve or create the object property
|
|
911
|
+
i2: OWLNamedIndividual = self.get_individual(
|
|
912
|
+
str(rel.get_object_individual())
|
|
913
|
+
) # Retrieve or create the related individual
|
|
914
|
+
|
|
915
|
+
deg: Degree = rel.get_degree()
|
|
916
|
+
if isinstance(r, OWLObjectProperty):
|
|
917
|
+
factory_call: typing.Callable = (
|
|
918
|
+
self.data_factory.getOWLObjectPropertyAssertionAxiom
|
|
919
|
+
)
|
|
920
|
+
else:
|
|
921
|
+
factory_call: typing.Callable = (
|
|
922
|
+
self.data_factory.getOWLDataPropertyAssertionAxiom
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
if deg.is_number_not_one(): # If the degree is not 1
|
|
926
|
+
# Create annotations
|
|
927
|
+
new_annotations: set[OWLAnnotation] = (
|
|
928
|
+
self.get_annotations_for_axiom(deg)
|
|
929
|
+
)
|
|
930
|
+
axiom: typing.Union[
|
|
931
|
+
OWLObjectPropertyAssertionAxiom, OWLDataPropertyAssertionAxiom
|
|
932
|
+
] = factory_call(r, i, i2, new_annotations)
|
|
933
|
+
else:
|
|
934
|
+
axiom: typing.Union[
|
|
935
|
+
OWLObjectPropertyAssertionAxiom, OWLDataPropertyAssertionAxiom
|
|
936
|
+
] = factory_call(r, i, i2)
|
|
937
|
+
self.manager.applyChange(AddAxiom(self.ontology, axiom))
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
def main():
|
|
941
|
+
if len(sys.argv) != 3:
|
|
942
|
+
Util.error(
|
|
943
|
+
"Error. Use: python fuzzydl_to_owl2.py <fuzzyDLOntology> <Owl2Ontology>",
|
|
944
|
+
file=sys.stderr,
|
|
945
|
+
)
|
|
946
|
+
sys.exit(-1)
|
|
947
|
+
|
|
948
|
+
converter = FuzzydlToOwl2(sys.argv[1], sys.argv[2])
|
|
949
|
+
converter.run()
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
if __name__ == "__main__":
|
|
953
|
+
main()
|