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,920 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import sys
|
|
5
|
+
import typing
|
|
6
|
+
from functools import partial
|
|
7
|
+
|
|
8
|
+
from fuzzy_dl_owl2.fuzzydl.assertion.assertion import Assertion
|
|
9
|
+
from fuzzy_dl_owl2.fuzzydl.concept.all_some_concept import AllSomeConcept
|
|
10
|
+
from fuzzy_dl_owl2.fuzzydl.concept.choquet_integral import ChoquetIntegral
|
|
11
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
12
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.crisp_concrete_concept import (
|
|
13
|
+
CrispConcreteConcept,
|
|
14
|
+
)
|
|
15
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
|
|
16
|
+
FuzzyConcreteConcept,
|
|
17
|
+
)
|
|
18
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.left_concrete_concept import (
|
|
19
|
+
LeftConcreteConcept,
|
|
20
|
+
)
|
|
21
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.right_concrete_concept import (
|
|
22
|
+
RightConcreteConcept,
|
|
23
|
+
)
|
|
24
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.trapezoidal_concrete_concept import (
|
|
25
|
+
TrapezoidalConcreteConcept,
|
|
26
|
+
)
|
|
27
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.triangular_concrete_concept import (
|
|
28
|
+
TriangularConcreteConcept,
|
|
29
|
+
)
|
|
30
|
+
from fuzzy_dl_owl2.fuzzydl.concept.has_value_concept import HasValueConcept
|
|
31
|
+
from fuzzy_dl_owl2.fuzzydl.concept.interface.has_weighted_concepts_interface import (
|
|
32
|
+
HasWeightedConceptsInterface,
|
|
33
|
+
)
|
|
34
|
+
from fuzzy_dl_owl2.fuzzydl.concept.modified.modified_concept import ModifiedConcept
|
|
35
|
+
from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
|
|
36
|
+
from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
|
|
37
|
+
from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
|
|
38
|
+
from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import QsugenoIntegral
|
|
39
|
+
from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
|
|
40
|
+
from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
|
|
41
|
+
from fuzzy_dl_owl2.fuzzydl.concept.value_concept import ValueConcept
|
|
42
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_concept import WeightedConcept
|
|
43
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_max_concept import WeightedMaxConcept
|
|
44
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_min_concept import WeightedMinConcept
|
|
45
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_concept import WeightedSumConcept
|
|
46
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_zero_concept import (
|
|
47
|
+
WeightedSumZeroConcept,
|
|
48
|
+
)
|
|
49
|
+
from fuzzy_dl_owl2.fuzzydl.concept_equivalence import ConceptEquivalence
|
|
50
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
|
|
51
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
|
|
52
|
+
from fuzzy_dl_owl2.fuzzydl.general_concept_inclusion import GeneralConceptInclusion
|
|
53
|
+
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
54
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
|
|
55
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
56
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import TriangularModifier
|
|
57
|
+
from fuzzy_dl_owl2.fuzzydl.parser.dl_parser import DLParser
|
|
58
|
+
from fuzzy_dl_owl2.fuzzydl.primitive_concept_definition import (
|
|
59
|
+
PrimitiveConceptDefinition,
|
|
60
|
+
)
|
|
61
|
+
from fuzzy_dl_owl2.fuzzydl.util import constants
|
|
62
|
+
from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType, ConcreteFeatureType
|
|
63
|
+
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
64
|
+
from fuzzy_dl_owl2.fuzzyowl2.util.constants import FuzzyOWL2Keyword
|
|
65
|
+
from pyowl2.abstracts.axiom import OWLAxiom
|
|
66
|
+
from pyowl2.abstracts.class_expression import OWLClassExpression
|
|
67
|
+
from pyowl2.abstracts.data_range import OWLDataRange
|
|
68
|
+
from pyowl2.abstracts.entity import OWLEntity
|
|
69
|
+
from pyowl2.axioms.assertion import OWLDataPropertyAssertion, OWLObjectPropertyAssertion
|
|
70
|
+
from pyowl2.axioms.assertion.class_assertion import OWLClassAssertion
|
|
71
|
+
from pyowl2.axioms.class_axiom.disjoint_classes import OWLDisjointClasses
|
|
72
|
+
from pyowl2.axioms.class_axiom.equivalent_classes import OWLEquivalentClasses
|
|
73
|
+
from pyowl2.axioms.class_axiom.sub_class_of import OWLSubClassOf
|
|
74
|
+
from pyowl2.axioms.data_property_axiom.data_property_domain import OWLDataPropertyDomain
|
|
75
|
+
from pyowl2.axioms.data_property_axiom.data_property_range import OWLDataPropertyRange
|
|
76
|
+
from pyowl2.axioms.data_property_axiom.functional_data_property import (
|
|
77
|
+
OWLFunctionalDataProperty,
|
|
78
|
+
)
|
|
79
|
+
from pyowl2.axioms.data_property_axiom.sub_data_property_of import OWLSubDataPropertyOf
|
|
80
|
+
from pyowl2.axioms.datatype_definition import OWLDatatypeDefinition
|
|
81
|
+
from pyowl2.axioms.declaration import OWLDeclaration
|
|
82
|
+
from pyowl2.axioms.object_property_axiom.functional_object_property import (
|
|
83
|
+
OWLFunctionalObjectProperty,
|
|
84
|
+
)
|
|
85
|
+
from pyowl2.axioms.object_property_axiom.inverse_object_properties import (
|
|
86
|
+
OWLInverseObjectProperties,
|
|
87
|
+
)
|
|
88
|
+
from pyowl2.axioms.object_property_axiom.object_property_domain import (
|
|
89
|
+
OWLObjectPropertyDomain,
|
|
90
|
+
)
|
|
91
|
+
from pyowl2.axioms.object_property_axiom.object_property_range import (
|
|
92
|
+
OWLObjectPropertyRange,
|
|
93
|
+
)
|
|
94
|
+
from pyowl2.axioms.object_property_axiom.reflexive_object_property import (
|
|
95
|
+
OWLReflexiveObjectProperty,
|
|
96
|
+
)
|
|
97
|
+
from pyowl2.axioms.object_property_axiom.sub_object_property_of import (
|
|
98
|
+
OWLSubObjectPropertyOf,
|
|
99
|
+
)
|
|
100
|
+
from pyowl2.axioms.object_property_axiom.symmetric_object_property import (
|
|
101
|
+
OWLSymmetricObjectProperty,
|
|
102
|
+
)
|
|
103
|
+
from pyowl2.axioms.object_property_axiom.transitive_object_property import (
|
|
104
|
+
OWLTransitiveObjectProperty,
|
|
105
|
+
)
|
|
106
|
+
from pyowl2.base.annotation import OWLAnnotation
|
|
107
|
+
from pyowl2.base.annotation_property import OWLAnnotationProperty
|
|
108
|
+
from pyowl2.base.datatype import OWLDatatype
|
|
109
|
+
from pyowl2.base.iri import IRI
|
|
110
|
+
from pyowl2.base.owl_class import OWLClass
|
|
111
|
+
from pyowl2.class_expression.data_all_values_from import OWLDataAllValuesFrom
|
|
112
|
+
from pyowl2.class_expression.data_has_value import OWLDataHasValue
|
|
113
|
+
from pyowl2.class_expression.data_some_values_from import OWLDataSomeValuesFrom
|
|
114
|
+
from pyowl2.class_expression.object_all_values_from import OWLObjectAllValuesFrom
|
|
115
|
+
from pyowl2.class_expression.object_complement_of import OWLObjectComplementOf
|
|
116
|
+
from pyowl2.class_expression.object_has_self import OWLObjectHasSelf
|
|
117
|
+
from pyowl2.class_expression.object_has_value import OWLObjectHasValue
|
|
118
|
+
from pyowl2.class_expression.object_intersection_of import OWLObjectIntersectionOf
|
|
119
|
+
from pyowl2.class_expression.object_some_values_from import OWLObjectSomeValuesFrom
|
|
120
|
+
from pyowl2.class_expression.object_union_of import OWLObjectUnionOf
|
|
121
|
+
from pyowl2.data_range.data_intersection_of import OWLDataIntersectionOf
|
|
122
|
+
from pyowl2.data_range.datatype_restriction import OWLDatatypeRestriction, OWLFacet
|
|
123
|
+
from pyowl2.expressions.data_property import OWLDataProperty
|
|
124
|
+
from pyowl2.expressions.object_property import OWLObjectProperty
|
|
125
|
+
from pyowl2.individual.named_individual import OWLNamedIndividual
|
|
126
|
+
from pyowl2.literal.literal import OWLLiteral
|
|
127
|
+
from pyowl2.ontology import OWLOntology
|
|
128
|
+
from rdflib import RDF, XSD, Literal, Namespace, URIRef
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
# @utils.timer_decorator
|
|
132
|
+
class FuzzydlToOwl2:
|
|
133
|
+
"""Convert FuzzyDL to OWL2"""
|
|
134
|
+
|
|
135
|
+
def __init__(
|
|
136
|
+
self,
|
|
137
|
+
input_file: str,
|
|
138
|
+
output_file: str,
|
|
139
|
+
# base_iri: str = "http://www.semanticweb.org/ontologies/fuzzydl_ontology.owl",
|
|
140
|
+
base_iri: str = "http://www.semanticweb.org/ontologies/fuzzydl_ontology#",
|
|
141
|
+
) -> None:
|
|
142
|
+
self.num_classes: int = 0
|
|
143
|
+
self.kb, _ = DLParser.get_kb(input_file)
|
|
144
|
+
self.ontology_path: str = base_iri
|
|
145
|
+
self.ontology_iri: IRI = IRI(Namespace(URIRef(base_iri)))
|
|
146
|
+
self.ontology: OWLOntology = OWLOntology(
|
|
147
|
+
self.ontology_iri, OWL1_annotations=True
|
|
148
|
+
)
|
|
149
|
+
self.fuzzyLabel: OWLAnnotationProperty = OWLAnnotationProperty(
|
|
150
|
+
IRI(self.ontology_iri.namespace, "fuzzyLabel")
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
self.ontology.add_axiom(OWLDeclaration(self.fuzzyLabel))
|
|
154
|
+
|
|
155
|
+
self.concepts: dict[str, OWLClassExpression] = dict()
|
|
156
|
+
self.datatypes: dict[str, OWLDatatype] = dict()
|
|
157
|
+
self.modifiers: dict[str, OWLDatatype] = dict()
|
|
158
|
+
self.input_FDL: str = input_file
|
|
159
|
+
self.output_FOWL: str = os.path.join(constants.RESULTS_PATH, output_file)
|
|
160
|
+
|
|
161
|
+
def iri(self, o: object) -> IRI:
|
|
162
|
+
"""Convert object to IRI string"""
|
|
163
|
+
return IRI(self.ontology_iri.namespace, str(o))
|
|
164
|
+
|
|
165
|
+
def get_base(self, c: Concept) -> OWLClassExpression:
|
|
166
|
+
"""Get the base class for a concept"""
|
|
167
|
+
if c.is_atomic():
|
|
168
|
+
return self.get_class(str(c))
|
|
169
|
+
return self.get_new_atomic_class(str(c))
|
|
170
|
+
|
|
171
|
+
@typing.overload
|
|
172
|
+
def get_class(self, name: str) -> OWLClassExpression: ...
|
|
173
|
+
|
|
174
|
+
@typing.overload
|
|
175
|
+
def get_class(self, c: Concept) -> OWLClassExpression: ...
|
|
176
|
+
|
|
177
|
+
def get_class(self, arg: typing.Union[str, Concept]) -> OWLClassExpression:
|
|
178
|
+
"""Get or create an OWL class"""
|
|
179
|
+
if isinstance(arg, str):
|
|
180
|
+
return self.__get_class_1(arg)
|
|
181
|
+
elif isinstance(arg, Concept):
|
|
182
|
+
return self.__get_class_2(arg)
|
|
183
|
+
else:
|
|
184
|
+
raise ValueError("Argument must be a string or a Concept")
|
|
185
|
+
|
|
186
|
+
def __get_class_1(self, name: str) -> OWLClassExpression:
|
|
187
|
+
"""Get or create an OWL class by name"""
|
|
188
|
+
cls = OWLClass(self.iri(name))
|
|
189
|
+
self.ontology.add_axiom(OWLDeclaration(cls))
|
|
190
|
+
return cls
|
|
191
|
+
|
|
192
|
+
def __get_class_2(self, c: Concept) -> OWLClassExpression:
|
|
193
|
+
"""Get or create an OWL class from a Concept"""
|
|
194
|
+
Util.debug(f"Getting class for concept -> {c}")
|
|
195
|
+
c_type: ConceptType = c.type
|
|
196
|
+
if c_type in (ConceptType.ATOMIC, ConceptType.CONCRETE):
|
|
197
|
+
cls = self.get_class(str(c))
|
|
198
|
+
self.ontology.add_axiom(OWLDeclaration(cls))
|
|
199
|
+
return cls
|
|
200
|
+
elif c_type == ConceptType.TOP:
|
|
201
|
+
return OWLClass.thing()
|
|
202
|
+
elif c_type == ConceptType.BOTTOM:
|
|
203
|
+
return OWLClass.nothing()
|
|
204
|
+
elif c_type in (
|
|
205
|
+
ConceptType.COMPLEMENT,
|
|
206
|
+
ConceptType.NOT_AT_MOST_VALUE,
|
|
207
|
+
ConceptType.NOT_AT_LEAST_VALUE,
|
|
208
|
+
ConceptType.NOT_EXACT_VALUE,
|
|
209
|
+
ConceptType.NOT_WEIGHTED,
|
|
210
|
+
ConceptType.NOT_W_SUM,
|
|
211
|
+
ConceptType.CONCRETE_COMPLEMENT,
|
|
212
|
+
ConceptType.MODIFIED_COMPLEMENT,
|
|
213
|
+
ConceptType.NOT_OWA,
|
|
214
|
+
ConceptType.NOT_QUANTIFIED_OWA,
|
|
215
|
+
ConceptType.NOT_CHOQUET_INTEGRAL,
|
|
216
|
+
ConceptType.NOT_SUGENO_INTEGRAL,
|
|
217
|
+
ConceptType.NOT_QUASI_SUGENO_INTEGRAL,
|
|
218
|
+
ConceptType.NOT_W_MAX,
|
|
219
|
+
ConceptType.NOT_W_MIN,
|
|
220
|
+
ConceptType.NOT_W_SUM_ZERO,
|
|
221
|
+
ConceptType.NOT_SELF,
|
|
222
|
+
ConceptType.NOT_HAS_VALUE,
|
|
223
|
+
):
|
|
224
|
+
return OWLObjectComplementOf(self.get_class(-c))
|
|
225
|
+
elif c_type in (
|
|
226
|
+
ConceptType.AND,
|
|
227
|
+
ConceptType.GOEDEL_AND,
|
|
228
|
+
ConceptType.LUKASIEWICZ_AND,
|
|
229
|
+
):
|
|
230
|
+
c: OperatorConcept = typing.cast(OperatorConcept, c)
|
|
231
|
+
return OWLObjectIntersectionOf([self.get_class(c1) for c1 in c.concepts])
|
|
232
|
+
elif c_type in (
|
|
233
|
+
ConceptType.OR,
|
|
234
|
+
ConceptType.GOEDEL_OR,
|
|
235
|
+
ConceptType.LUKASIEWICZ_OR,
|
|
236
|
+
):
|
|
237
|
+
c: OperatorConcept = typing.cast(OperatorConcept, c)
|
|
238
|
+
return OWLObjectUnionOf([self.get_class(c1) for c1 in c.concepts])
|
|
239
|
+
elif c_type == ConceptType.SOME:
|
|
240
|
+
c: AllSomeConcept = typing.cast(AllSomeConcept, c)
|
|
241
|
+
if str(c.curr_concept) in self.datatypes:
|
|
242
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
243
|
+
self.get_data_property(c.role)
|
|
244
|
+
)
|
|
245
|
+
assert isinstance(dp, OWLDataProperty)
|
|
246
|
+
d: OWLDatatype = self.datatypes.get(str(c.curr_concept))
|
|
247
|
+
return OWLDataSomeValuesFrom([dp], d)
|
|
248
|
+
else:
|
|
249
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
250
|
+
self.get_object_property(c.role)
|
|
251
|
+
)
|
|
252
|
+
assert isinstance(op, OWLObjectProperty)
|
|
253
|
+
c2: OWLClassExpression = self.get_class(c.curr_concept)
|
|
254
|
+
return OWLObjectSomeValuesFrom(op, c2)
|
|
255
|
+
elif c_type == ConceptType.ALL:
|
|
256
|
+
c: AllSomeConcept = typing.cast(AllSomeConcept, c)
|
|
257
|
+
if str(c.curr_concept) in self.datatypes:
|
|
258
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
259
|
+
self.get_data_property(c.role)
|
|
260
|
+
)
|
|
261
|
+
assert isinstance(dp, OWLDataProperty)
|
|
262
|
+
d: OWLDatatype = self.datatypes.get(str(c.curr_concept))
|
|
263
|
+
return OWLDataAllValuesFrom([dp], d)
|
|
264
|
+
else:
|
|
265
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
266
|
+
self.get_object_property(c.role)
|
|
267
|
+
)
|
|
268
|
+
assert isinstance(op, OWLObjectProperty)
|
|
269
|
+
c2: OWLClassExpression = self.get_class(c.curr_concept)
|
|
270
|
+
return OWLObjectAllValuesFrom(op, c2)
|
|
271
|
+
elif c_type == ConceptType.MODIFIED:
|
|
272
|
+
c: ModifiedConcept = typing.cast(ModifiedConcept, c)
|
|
273
|
+
if str(c) in self.concepts:
|
|
274
|
+
return self.concepts.get(str(c))
|
|
275
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
276
|
+
c3: OWLClassExpression = self.get_base(c.c1)
|
|
277
|
+
self.concepts[str(c)] = c3
|
|
278
|
+
annotation: str = (
|
|
279
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
280
|
+
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',
|
|
281
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>",
|
|
282
|
+
)
|
|
283
|
+
self.add_entity_annotation(annotation, c4)
|
|
284
|
+
return c4
|
|
285
|
+
elif c_type == ConceptType.SELF:
|
|
286
|
+
c: SelfConcept = typing.cast(SelfConcept, c)
|
|
287
|
+
owl_obj_property: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
288
|
+
self.get_object_property(c.role)
|
|
289
|
+
)
|
|
290
|
+
assert isinstance(owl_obj_property, OWLObjectProperty)
|
|
291
|
+
return OWLObjectHasSelf(owl_obj_property)
|
|
292
|
+
elif c_type == ConceptType.HAS_VALUE:
|
|
293
|
+
c: HasValueConcept = typing.cast(HasValueConcept, c)
|
|
294
|
+
owl_obj_property: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
295
|
+
self.get_object_property(c.role)
|
|
296
|
+
)
|
|
297
|
+
assert isinstance(owl_obj_property, OWLObjectProperty)
|
|
298
|
+
ind: OWLNamedIndividual = self.get_individual(str(c.value))
|
|
299
|
+
return OWLObjectHasValue(owl_obj_property, ind)
|
|
300
|
+
elif c_type in (
|
|
301
|
+
ConceptType.AT_MOST_VALUE,
|
|
302
|
+
ConceptType.AT_LEAST_VALUE,
|
|
303
|
+
ConceptType.EXACT_VALUE,
|
|
304
|
+
):
|
|
305
|
+
c: ValueConcept = typing.cast(ValueConcept, c)
|
|
306
|
+
if isinstance(c.value, int):
|
|
307
|
+
datatype: OWLDatatype = OWLDatatype(XSD.integer)
|
|
308
|
+
literal: OWLLiteral = OWLLiteral(Literal(c.value, datatype=XSD.integer))
|
|
309
|
+
elif isinstance(c.value, float):
|
|
310
|
+
datatype: OWLDatatype = OWLDatatype(XSD.decimal)
|
|
311
|
+
literal: OWLLiteral = OWLLiteral(Literal(c.value, datatype=XSD.decimal))
|
|
312
|
+
elif isinstance(c.value, str):
|
|
313
|
+
datatype: OWLDatatype = OWLDatatype(RDF.PlainLiteral)
|
|
314
|
+
literal: OWLLiteral = OWLLiteral(
|
|
315
|
+
Literal(c.value, datatype=RDF.PlainLiteral)
|
|
316
|
+
)
|
|
317
|
+
if c_type == ConceptType.AT_LEAST_VALUE:
|
|
318
|
+
data_range: OWLDataRange = OWLDatatypeRestriction(
|
|
319
|
+
datatype, [OWLFacet(OWLFacet.MIN_INCLUSIVE, literal)]
|
|
320
|
+
)
|
|
321
|
+
return OWLDataSomeValuesFrom(self.get_data_property(c.role), data_range)
|
|
322
|
+
elif c_type == ConceptType.AT_MOST_VALUE:
|
|
323
|
+
data_range: OWLDataRange = OWLDatatypeRestriction(
|
|
324
|
+
datatype, [OWLFacet(OWLFacet.MAX_INCLUSIVE, literal)]
|
|
325
|
+
)
|
|
326
|
+
return OWLDataSomeValuesFrom(self.get_data_property(c.role), data_range)
|
|
327
|
+
else:
|
|
328
|
+
return OWLDataHasValue(self.get_data_property(c.role), literal)
|
|
329
|
+
elif c_type == ConceptType.WEIGHTED:
|
|
330
|
+
c: WeightedConcept = typing.cast(WeightedConcept, c)
|
|
331
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
332
|
+
c3: OWLClassExpression = self.get_base(c.c1)
|
|
333
|
+
annotation: str = (
|
|
334
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
335
|
+
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',
|
|
336
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>",
|
|
337
|
+
)
|
|
338
|
+
self.add_entity_annotation(annotation, c3)
|
|
339
|
+
return c4
|
|
340
|
+
elif c_type in (
|
|
341
|
+
ConceptType.W_MAX,
|
|
342
|
+
ConceptType.W_MIN,
|
|
343
|
+
ConceptType.W_SUM,
|
|
344
|
+
ConceptType.W_SUM_ZERO,
|
|
345
|
+
):
|
|
346
|
+
return self.__get_class_weighted_min_max_sum(c)
|
|
347
|
+
elif c_type in (
|
|
348
|
+
ConceptType.OWA,
|
|
349
|
+
ConceptType.QUANTIFIED_OWA,
|
|
350
|
+
ConceptType.CHOQUET_INTEGRAL,
|
|
351
|
+
ConceptType.SUGENO_INTEGRAL,
|
|
352
|
+
ConceptType.QUASI_SUGENO_INTEGRAL,
|
|
353
|
+
):
|
|
354
|
+
return self.__get_class_weighted(c)
|
|
355
|
+
cls = OWLClass(self.iri(str(c)))
|
|
356
|
+
self.ontology.add_axiom(OWLDeclaration(cls))
|
|
357
|
+
return cls
|
|
358
|
+
|
|
359
|
+
def __get_class_weighted_min_max_sum(self, c: Concept) -> OWLClassExpression:
|
|
360
|
+
"""Get the class for weighted min, max, sum, or sum zero"""
|
|
361
|
+
type_dict: dict[ConceptType, str] = {
|
|
362
|
+
ConceptType.W_MAX: FuzzyOWL2Keyword.WEIGHTED_MAXIMUM.get_str_value(),
|
|
363
|
+
ConceptType.W_MIN: FuzzyOWL2Keyword.WEIGHTED_MINIMUM.get_str_value(),
|
|
364
|
+
ConceptType.W_SUM: FuzzyOWL2Keyword.WEIGHTED_SUM.get_str_value(),
|
|
365
|
+
ConceptType.W_SUM_ZERO: FuzzyOWL2Keyword.WEIGHTED_SUMZERO.get_str_value(),
|
|
366
|
+
}
|
|
367
|
+
type_cast: dict[ConceptType, typing.Callable] = {
|
|
368
|
+
ConceptType.W_MAX: partial(typing.cast, WeightedMaxConcept),
|
|
369
|
+
ConceptType.W_MIN: partial(typing.cast, WeightedMinConcept),
|
|
370
|
+
ConceptType.W_SUM: partial(typing.cast, WeightedSumConcept),
|
|
371
|
+
ConceptType.W_SUM_ZERO: partial(typing.cast, WeightedSumZeroConcept),
|
|
372
|
+
}
|
|
373
|
+
if c.type not in type_dict:
|
|
374
|
+
return None
|
|
375
|
+
curr_concept: HasWeightedConceptsInterface = type_cast[c.type](c)
|
|
376
|
+
c3: OWLClassExpression = self.get_new_atomic_class(str(curr_concept))
|
|
377
|
+
|
|
378
|
+
annotation: str = (
|
|
379
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
380
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{type_dict[c.type]}">\n ',
|
|
381
|
+
)
|
|
382
|
+
for i in range(len(curr_concept.concepts)):
|
|
383
|
+
c5: OWLClassExpression = self.get_base(curr_concept.concepts[i])
|
|
384
|
+
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'
|
|
385
|
+
annotation: str = (
|
|
386
|
+
f"\t</{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} >\n</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} >"
|
|
387
|
+
)
|
|
388
|
+
self.add_entity_annotation(annotation, c3)
|
|
389
|
+
return c3
|
|
390
|
+
|
|
391
|
+
def __get_class_weighted(self, c: Concept) -> OWLClassExpression:
|
|
392
|
+
"""Get the class for OWA, Quantified OWA, Choquet Integral, Sugeno Integral, or Quasi Sugeno Integral"""
|
|
393
|
+
type_dict: dict[ConceptType, str] = {
|
|
394
|
+
ConceptType.OWA: FuzzyOWL2Keyword.OWA.get_str_value(),
|
|
395
|
+
ConceptType.QUANTIFIED_OWA: FuzzyOWL2Keyword.Q_OWA.get_str_value(),
|
|
396
|
+
ConceptType.CHOQUET_INTEGRAL: FuzzyOWL2Keyword.CHOQUET.get_str_value(),
|
|
397
|
+
ConceptType.SUGENO_INTEGRAL: FuzzyOWL2Keyword.SUGENO.get_str_value(),
|
|
398
|
+
ConceptType.QUASI_SUGENO_INTEGRAL: FuzzyOWL2Keyword.QUASI_SUGENO.get_str_value(),
|
|
399
|
+
}
|
|
400
|
+
type_cast: dict[ConceptType, typing.Callable] = {
|
|
401
|
+
ConceptType.OWA: partial(typing.cast, OwaConcept),
|
|
402
|
+
ConceptType.QUANTIFIED_OWA: partial(typing.cast, QowaConcept),
|
|
403
|
+
ConceptType.CHOQUET_INTEGRAL: partial(typing.cast, ChoquetIntegral),
|
|
404
|
+
ConceptType.SUGENO_INTEGRAL: partial(typing.cast, SugenoIntegral),
|
|
405
|
+
ConceptType.QUASI_SUGENO_INTEGRAL: partial(typing.cast, QsugenoIntegral),
|
|
406
|
+
}
|
|
407
|
+
if c.type not in type_dict:
|
|
408
|
+
return None
|
|
409
|
+
curr_concept: HasWeightedConceptsInterface = type_cast[c.type](c)
|
|
410
|
+
c4: OWLClassExpression = self.get_new_atomic_class(str(c))
|
|
411
|
+
annotation: str = (
|
|
412
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.CONCEPT.get_str_value()}">\n',
|
|
413
|
+
f'\t<{FuzzyOWL2Keyword.CONCEPT.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{type_dict[c.type]}">\n',
|
|
414
|
+
f"\t\t<{FuzzyOWL2Keyword.WEIGHTS.get_tag_name()}>\n",
|
|
415
|
+
)
|
|
416
|
+
for d in curr_concept.weights:
|
|
417
|
+
annotation += f"\t\t\t<{FuzzyOWL2Keyword.WEIGHT.get_tag_name()}>{d}</{FuzzyOWL2Keyword.WEIGHT.get_tag_name()}>\n"
|
|
418
|
+
annotation += f"\t\t</{FuzzyOWL2Keyword.WEIGHTS.get_tag_name()}>\n\t\t<{FuzzyOWL2Keyword.CONCEPT_NAMES.get_tag_name()}>\n"
|
|
419
|
+
for ci in curr_concept.concepts:
|
|
420
|
+
c5: OWLClassExpression = self.get_base(ci)
|
|
421
|
+
annotation += f"\t\t\t<{FuzzyOWL2Keyword.NAME.get_tag_name()}>{c5}</{FuzzyOWL2Keyword.NAME.get_tag_name()}>\n"
|
|
422
|
+
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()}>"
|
|
423
|
+
self.add_entity_annotation(annotation, c4)
|
|
424
|
+
return c4
|
|
425
|
+
|
|
426
|
+
def get_new_atomic_class(self, name: str) -> OWLClassExpression:
|
|
427
|
+
"""Get or create a new atomic class"""
|
|
428
|
+
Util.debug(f"Getting new atomic concept -> {name}")
|
|
429
|
+
c = self.concepts.get(name)
|
|
430
|
+
if c is not None:
|
|
431
|
+
return c
|
|
432
|
+
|
|
433
|
+
self.num_classes += 1
|
|
434
|
+
Util.debug(f"Creating new atomic concept -> {name}")
|
|
435
|
+
c2: OWLClass = OWLClass(self.iri(f"class__{self.num_classes}"))
|
|
436
|
+
self.concepts[name] = c2
|
|
437
|
+
self.ontology.add_axiom(OWLDeclaration(c2))
|
|
438
|
+
return c2
|
|
439
|
+
|
|
440
|
+
def exist_object_property(self, role: str) -> bool:
|
|
441
|
+
"""Check if an object property exists"""
|
|
442
|
+
iri: IRI = self.iri(role)
|
|
443
|
+
return self.ontology.getter.exists_object_property(iri.to_uriref())
|
|
444
|
+
# return any(
|
|
445
|
+
# typing.cast(OWLObjectProperty, typing.cast(OWLDeclaration, prop).entity).iri
|
|
446
|
+
# == iri
|
|
447
|
+
# for prop in self.ontology.get_axioms(RDFXMLGetterTypes.OBJECT_PROPERTIES)
|
|
448
|
+
# )
|
|
449
|
+
|
|
450
|
+
def exist_data_property(self, role: str) -> bool:
|
|
451
|
+
"""Check if a data property exists"""
|
|
452
|
+
iri: IRI = self.iri(role)
|
|
453
|
+
return self.ontology.getter.exists_data_property(iri.to_uriref())
|
|
454
|
+
# return any(
|
|
455
|
+
# typing.cast(OWLDataProperty, typing.cast(OWLDeclaration, prop).entity).iri
|
|
456
|
+
# == iri
|
|
457
|
+
# for prop in self.ontology.get_axioms(RDFXMLGetterTypes.DATA_PROPERTIES)
|
|
458
|
+
# )
|
|
459
|
+
|
|
460
|
+
def get_object_property(
|
|
461
|
+
self, role: str
|
|
462
|
+
) -> typing.Union[OWLDataProperty, OWLObjectProperty]:
|
|
463
|
+
"""Get or create an object property"""
|
|
464
|
+
Util.debug(f"Getting object property -> {role}")
|
|
465
|
+
if self.exist_data_property(role):
|
|
466
|
+
return self.get_data_property(role)
|
|
467
|
+
obj = OWLObjectProperty(self.iri(role))
|
|
468
|
+
self.ontology.add_axiom(OWLDeclaration(obj))
|
|
469
|
+
return obj
|
|
470
|
+
|
|
471
|
+
def get_data_property(
|
|
472
|
+
self, role: str
|
|
473
|
+
) -> typing.Union[OWLDataProperty, OWLObjectProperty]:
|
|
474
|
+
"""Get or create a data property"""
|
|
475
|
+
Util.debug(f"Getting data property -> {role}")
|
|
476
|
+
if self.exist_object_property(role):
|
|
477
|
+
return self.get_object_property(role)
|
|
478
|
+
data = OWLDataProperty(self.iri(role))
|
|
479
|
+
self.ontology.add_axiom(OWLDeclaration(data))
|
|
480
|
+
return data
|
|
481
|
+
|
|
482
|
+
def get_individual(self, name: str) -> OWLNamedIndividual:
|
|
483
|
+
"""Get or create a named individual"""
|
|
484
|
+
Util.debug(f"Getting individual -> {name}")
|
|
485
|
+
ind = OWLNamedIndividual(self.iri(f"{name}_Individual"))
|
|
486
|
+
self.ontology.add_axiom(OWLDeclaration(ind))
|
|
487
|
+
return ind
|
|
488
|
+
|
|
489
|
+
def to_owl_annotation(self, annotation: str) -> OWLAnnotation:
|
|
490
|
+
"""Convert a string to an OWL annotation"""
|
|
491
|
+
Util.debug(f"Converting annotation to OWL -> {annotation}")
|
|
492
|
+
return OWLAnnotation(
|
|
493
|
+
self.fuzzyLabel,
|
|
494
|
+
OWLLiteral(
|
|
495
|
+
Literal(annotation, datatype=RDF.PlainLiteral),
|
|
496
|
+
),
|
|
497
|
+
)
|
|
498
|
+
|
|
499
|
+
def add_ontology_annotation(self, annotation: str) -> None:
|
|
500
|
+
"""Add annotation to the ontology"""
|
|
501
|
+
Util.debug(f"Adding annotation to ontology -> {annotation}")
|
|
502
|
+
comment: OWLAnnotation = self.to_owl_annotation(annotation)
|
|
503
|
+
self.ontology.add_annotation(comment)
|
|
504
|
+
|
|
505
|
+
def add_entity_annotation(self, annotation: str, entity: OWLEntity) -> None:
|
|
506
|
+
"""Add annotation to an entity"""
|
|
507
|
+
# define_datatype_in_ontology(entity, self.iri(entity), self.ontology)
|
|
508
|
+
Util.debug(f"Adding annotation to entity {entity} -> {annotation}")
|
|
509
|
+
owl_annotation: OWLAnnotation = self.to_owl_annotation(annotation)
|
|
510
|
+
# axiom: OWLAnnotationAssertion = OWLAnnotationAssertion(
|
|
511
|
+
# entity.iri, self.fuzzyLabel, owl_annotation
|
|
512
|
+
# )
|
|
513
|
+
# self.ontology.add_axiom(axiom)
|
|
514
|
+
self.ontology.add_annotation_to_element(entity, [owl_annotation])
|
|
515
|
+
|
|
516
|
+
def get_annotations_for_axiom(
|
|
517
|
+
self, value: typing.Union[float, DegreeNumeric]
|
|
518
|
+
) -> set[OWLAnnotation]:
|
|
519
|
+
"""Get annotations for an axiom with degree"""
|
|
520
|
+
if isinstance(value, float):
|
|
521
|
+
n = value
|
|
522
|
+
elif isinstance(value, DegreeNumeric): # Degree object
|
|
523
|
+
n = value.get_numerical_value()
|
|
524
|
+
|
|
525
|
+
annotation_text: str = (
|
|
526
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.AXIOM.get_str_value()}">\n'
|
|
527
|
+
f'\t<{FuzzyOWL2Keyword.DEGREE_DEF.get_tag_name()} {FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value()}="{n}"/>\n'
|
|
528
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
529
|
+
)
|
|
530
|
+
annotation: OWLAnnotation = self.to_owl_annotation(annotation_text)
|
|
531
|
+
return set([annotation])
|
|
532
|
+
|
|
533
|
+
def annotate_gci(self, gci: GeneralConceptInclusion) -> None:
|
|
534
|
+
"""Annotate a General Concept Inclusion (GCI)"""
|
|
535
|
+
c1: OWLClassExpression = self.get_class(gci.get_subsumed())
|
|
536
|
+
c2: OWLClassExpression = self.get_class(gci.get_subsumer())
|
|
537
|
+
deg: Degree = gci.get_degree()
|
|
538
|
+
Util.debug(f"Annotate GCI -> {c1} - {c2} - {deg}")
|
|
539
|
+
if deg.is_number_not_one():
|
|
540
|
+
new_annotations: set[OWLAnnotation] = self.get_annotations_for_axiom(deg)
|
|
541
|
+
axiom: OWLSubClassOf = OWLSubClassOf(c1, c2, list(new_annotations))
|
|
542
|
+
else:
|
|
543
|
+
axiom: OWLSubClassOf = OWLSubClassOf(c1, c2)
|
|
544
|
+
self.ontology.add_axiom(axiom)
|
|
545
|
+
|
|
546
|
+
def annotate_pcd(
|
|
547
|
+
self, c1: OWLClassExpression, pcd: PrimitiveConceptDefinition
|
|
548
|
+
) -> None:
|
|
549
|
+
"""Annotate a Primitive Concept Definition (PCD)"""
|
|
550
|
+
c2: OWLClassExpression = self.get_class(pcd.get_definition())
|
|
551
|
+
n: float = pcd.get_degree()
|
|
552
|
+
Util.debug(f"Annotate PCD -> {c1} - {c2} - {n}")
|
|
553
|
+
if n != 1.0:
|
|
554
|
+
new_annotations: set[OWLAnnotation] = self.get_annotations_for_axiom(n)
|
|
555
|
+
axiom: OWLSubClassOf = OWLSubClassOf(c1, c2, list(new_annotations))
|
|
556
|
+
else:
|
|
557
|
+
axiom: OWLSubClassOf = OWLSubClassOf(c1, c2)
|
|
558
|
+
self.ontology.add_axiom(axiom)
|
|
559
|
+
|
|
560
|
+
def run(self) -> None:
|
|
561
|
+
"""Execute the conversion process"""
|
|
562
|
+
# Set fuzzy logic type
|
|
563
|
+
logic = str(constants.KNOWLEDGE_BASE_SEMANTICS)
|
|
564
|
+
|
|
565
|
+
if logic:
|
|
566
|
+
annotation: str = (
|
|
567
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.ONTOLOGY.get_str_value()}">\n'
|
|
568
|
+
f'\t<{FuzzyOWL2Keyword.FUZZY_LOGIC.get_tag_name()} {FuzzyOWL2Keyword.LOGIC.get_str_value()}="{logic}" />\n'
|
|
569
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
570
|
+
)
|
|
571
|
+
self.add_ontology_annotation(annotation)
|
|
572
|
+
|
|
573
|
+
# Process concrete concepts
|
|
574
|
+
for c in self.kb.concrete_concepts.values():
|
|
575
|
+
self._process_concrete_concept(c)
|
|
576
|
+
|
|
577
|
+
# Process modifiers
|
|
578
|
+
for mod in self.kb.modifiers.values():
|
|
579
|
+
self._process_modifier(mod)
|
|
580
|
+
|
|
581
|
+
# Process assertions
|
|
582
|
+
for ass in self.kb.assertions:
|
|
583
|
+
self._process_assertion(ass)
|
|
584
|
+
|
|
585
|
+
# Process individuals
|
|
586
|
+
for ind in self.kb.individuals.values():
|
|
587
|
+
self._process_individual(ind)
|
|
588
|
+
|
|
589
|
+
for a in self.kb.axioms_A_equiv_C:
|
|
590
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
591
|
+
for c in self.kb.axioms_A_equiv_C[a]:
|
|
592
|
+
c2: OWLClassExpression = self.get_class(c)
|
|
593
|
+
Util.debug(f"Process axioms_A_equiv_C -> {c1} - {c2}")
|
|
594
|
+
axiom: OWLAxiom = OWLEquivalentClasses([c1, c2])
|
|
595
|
+
self.ontology.add_axiom(axiom)
|
|
596
|
+
|
|
597
|
+
for a in self.kb.axioms_A_is_a_B:
|
|
598
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
599
|
+
for pcd in self.kb.axioms_A_is_a_B[a]:
|
|
600
|
+
Util.debug(f"Process axioms_A_is_a_B -> {c1} - {pcd}")
|
|
601
|
+
self.annotate_pcd(c1, pcd)
|
|
602
|
+
|
|
603
|
+
for a in self.kb.axioms_A_is_a_C:
|
|
604
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
605
|
+
for pcd in self.kb.axioms_A_is_a_C[a]:
|
|
606
|
+
Util.debug(f"Process axioms_A_is_a_C -> {c1} - {pcd}")
|
|
607
|
+
self.annotate_pcd(c1, pcd)
|
|
608
|
+
|
|
609
|
+
for gcis in self.kb.axioms_C_is_a_D.values():
|
|
610
|
+
for gci in gcis:
|
|
611
|
+
Util.debug(f"Process axioms_C_is_a_D -> {gci}")
|
|
612
|
+
self.annotate_gci(gci)
|
|
613
|
+
|
|
614
|
+
for gcis in self.kb.axioms_C_is_a_A.values():
|
|
615
|
+
for gci in gcis:
|
|
616
|
+
Util.debug(f"Process axioms_C_is_a_A -> {gci}")
|
|
617
|
+
self.annotate_gci(gci)
|
|
618
|
+
|
|
619
|
+
for ce in self.kb.axioms_C_equiv_D:
|
|
620
|
+
ce: ConceptEquivalence = typing.cast(ConceptEquivalence, ce)
|
|
621
|
+
Util.debug(f"Process axioms_C_equiv_D -> {ce}")
|
|
622
|
+
c1: OWLClassExpression = self.get_class(ce.get_c1())
|
|
623
|
+
c2: OWLClassExpression = self.get_class(ce.get_c2())
|
|
624
|
+
axiom: OWLAxiom = OWLEquivalentClasses([c1, c2])
|
|
625
|
+
self.ontology.add_axiom(axiom)
|
|
626
|
+
|
|
627
|
+
for a in self.kb.t_disjoints:
|
|
628
|
+
c1: OWLClassExpression = self.get_class(a)
|
|
629
|
+
for disj_C in self.kb.t_disjoints[a]:
|
|
630
|
+
Util.debug(f"Process t_dis -> {c1} - {disj_C}")
|
|
631
|
+
if a >= disj_C:
|
|
632
|
+
continue
|
|
633
|
+
c2: OWLClassExpression = self.get_class(disj_C)
|
|
634
|
+
axiom: OWLAxiom = OWLDisjointClasses([c1, c2])
|
|
635
|
+
self.ontology.add_axiom(axiom)
|
|
636
|
+
|
|
637
|
+
for r in self.kb.domain_restrictions:
|
|
638
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
639
|
+
self.get_object_property(r)
|
|
640
|
+
)
|
|
641
|
+
for c in self.kb.domain_restrictions[r]:
|
|
642
|
+
Util.debug(f"Process domain restriction -> {c}")
|
|
643
|
+
cl: OWLClassExpression = self.get_class(c)
|
|
644
|
+
if isinstance(op, OWLObjectProperty):
|
|
645
|
+
axiom: OWLAxiom = OWLObjectPropertyDomain(op, cl)
|
|
646
|
+
else:
|
|
647
|
+
axiom: OWLAxiom = OWLDataPropertyDomain(op, cl)
|
|
648
|
+
self.ontology.add_axiom(axiom)
|
|
649
|
+
|
|
650
|
+
for r in self.kb.range_restrictions:
|
|
651
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
652
|
+
self.get_object_property(r)
|
|
653
|
+
)
|
|
654
|
+
for c in self.kb.range_restrictions[r]:
|
|
655
|
+
Util.debug(f"Process range restriction -> {c}")
|
|
656
|
+
cl: OWLClassExpression = self.get_class(c)
|
|
657
|
+
if isinstance(op, OWLObjectProperty):
|
|
658
|
+
axiom: OWLAxiom = OWLObjectPropertyRange(op, cl)
|
|
659
|
+
else:
|
|
660
|
+
axiom: OWLAxiom = OWLDataPropertyRange(op, cl)
|
|
661
|
+
self.ontology.add_axiom(axiom)
|
|
662
|
+
|
|
663
|
+
for r in self.kb.reflexive_roles:
|
|
664
|
+
Util.debug(f"Process reflexive role -> {r}")
|
|
665
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
666
|
+
self.get_object_property(r)
|
|
667
|
+
)
|
|
668
|
+
assert isinstance(op, OWLObjectProperty)
|
|
669
|
+
axiom: OWLAxiom = OWLReflexiveObjectProperty(op)
|
|
670
|
+
self.ontology.add_axiom(axiom)
|
|
671
|
+
|
|
672
|
+
for r in self.kb.symmetric_roles:
|
|
673
|
+
Util.debug(f"Process symmetric role -> {r}")
|
|
674
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
675
|
+
self.get_object_property(r)
|
|
676
|
+
)
|
|
677
|
+
assert isinstance(op, OWLObjectProperty)
|
|
678
|
+
axiom: OWLAxiom = OWLSymmetricObjectProperty(op)
|
|
679
|
+
self.ontology.add_axiom(axiom)
|
|
680
|
+
|
|
681
|
+
for r in self.kb.transitive_roles:
|
|
682
|
+
Util.debug(f"Process transitive role -> {r}")
|
|
683
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
684
|
+
self.get_object_property(r)
|
|
685
|
+
)
|
|
686
|
+
assert isinstance(op, OWLObjectProperty)
|
|
687
|
+
axiom: OWLAxiom = OWLTransitiveObjectProperty(op)
|
|
688
|
+
self.ontology.add_axiom(axiom)
|
|
689
|
+
|
|
690
|
+
for r, r_set in self.kb.inverse_roles.items():
|
|
691
|
+
Util.debug(f"Process inverse role -> inv_role = {r}")
|
|
692
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
693
|
+
self.get_object_property(r)
|
|
694
|
+
)
|
|
695
|
+
for s in r_set:
|
|
696
|
+
Util.debug(f"Process inverse role -> role = {s}")
|
|
697
|
+
op2: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
698
|
+
self.get_object_property(s)
|
|
699
|
+
)
|
|
700
|
+
assert isinstance(op, OWLObjectProperty) and isinstance(
|
|
701
|
+
op2, OWLObjectProperty
|
|
702
|
+
)
|
|
703
|
+
axiom: OWLAxiom = OWLInverseObjectProperties(op, op2)
|
|
704
|
+
self.ontology.add_axiom(axiom)
|
|
705
|
+
|
|
706
|
+
for r in self.kb.roles_with_parents:
|
|
707
|
+
Util.debug(f"Process role with parents -> role = {r}")
|
|
708
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
709
|
+
self.get_object_property(r)
|
|
710
|
+
)
|
|
711
|
+
par: dict[str, float] = self.kb.roles_with_parents.get(r, dict())
|
|
712
|
+
for s in par:
|
|
713
|
+
Util.debug(f"Process role with parents -> parent = {s}")
|
|
714
|
+
op2: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
715
|
+
self.get_object_property(s)
|
|
716
|
+
)
|
|
717
|
+
if isinstance(op, OWLObjectProperty) and isinstance(
|
|
718
|
+
op2, OWLObjectProperty
|
|
719
|
+
):
|
|
720
|
+
axiom: OWLAxiom = OWLSubObjectPropertyOf(op, op2)
|
|
721
|
+
elif isinstance(op, OWLDataProperty) and isinstance(
|
|
722
|
+
op2, OWLDataProperty
|
|
723
|
+
):
|
|
724
|
+
axiom: OWLAxiom = OWLSubDataPropertyOf(op, op2)
|
|
725
|
+
else:
|
|
726
|
+
raise ValueError(
|
|
727
|
+
f"Invalid property types: {type(op)} and {type(op2)}"
|
|
728
|
+
)
|
|
729
|
+
self.ontology.add_axiom(axiom)
|
|
730
|
+
|
|
731
|
+
for r in self.kb.functional_roles:
|
|
732
|
+
Util.debug(f"Process functional role -> {r}")
|
|
733
|
+
if r in self.kb.concrete_features:
|
|
734
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
735
|
+
self.get_data_property(r)
|
|
736
|
+
)
|
|
737
|
+
if isinstance(dp, OWLDataProperty):
|
|
738
|
+
axiom: OWLAxiom = OWLFunctionalDataProperty(dp)
|
|
739
|
+
else:
|
|
740
|
+
axiom: OWLAxiom = OWLFunctionalObjectProperty(dp)
|
|
741
|
+
else:
|
|
742
|
+
op: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
743
|
+
self.get_object_property(r)
|
|
744
|
+
)
|
|
745
|
+
if isinstance(op, OWLObjectProperty):
|
|
746
|
+
axiom: OWLAxiom = OWLFunctionalObjectProperty(op)
|
|
747
|
+
else:
|
|
748
|
+
axiom: OWLAxiom = OWLFunctionalDataProperty(op)
|
|
749
|
+
self.ontology.add_axiom(axiom)
|
|
750
|
+
|
|
751
|
+
for cf_name, cf in self.kb.concrete_features.items():
|
|
752
|
+
if cf is None:
|
|
753
|
+
continue
|
|
754
|
+
Util.debug(f"Process concrete feature {cf_name} -> {cf}")
|
|
755
|
+
cf_type: ConcreteFeatureType = cf.get_type()
|
|
756
|
+
dp: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
757
|
+
self.get_data_property(cf_name)
|
|
758
|
+
)
|
|
759
|
+
if cf_type == ConcreteFeatureType.BOOLEAN:
|
|
760
|
+
dt: OWLDatatype = OWLDatatype(XSD.boolean)
|
|
761
|
+
elif cf_type == ConcreteFeatureType.INTEGER:
|
|
762
|
+
dt: OWLDatatype = OWLDatatype(XSD.integer)
|
|
763
|
+
elif cf_type == ConcreteFeatureType.REAL:
|
|
764
|
+
dt: OWLDatatype = OWLDatatype(XSD.decimal)
|
|
765
|
+
elif cf_type == ConcreteFeatureType.STRING:
|
|
766
|
+
dt: OWLDatatype = OWLDatatype(RDF.PlainLiteral)
|
|
767
|
+
# Util.warning(
|
|
768
|
+
# "To Implement: String Datatype Property Range conversion"
|
|
769
|
+
# )
|
|
770
|
+
if isinstance(dp, OWLDataProperty):
|
|
771
|
+
axiom: OWLAxiom = OWLDataPropertyRange(dp, dt)
|
|
772
|
+
else:
|
|
773
|
+
axiom: OWLAxiom = OWLObjectPropertyRange(dp, dt)
|
|
774
|
+
self.ontology.add_axiom(axiom)
|
|
775
|
+
|
|
776
|
+
# Save ontology
|
|
777
|
+
try:
|
|
778
|
+
self.ontology.save(os.path.abspath(self.output_FOWL))
|
|
779
|
+
except Exception as ex:
|
|
780
|
+
Util.error(f"Error saving ontology: {ex}", file=sys.stderr)
|
|
781
|
+
raise ex
|
|
782
|
+
|
|
783
|
+
def _process_concrete_concept(self, c: FuzzyConcreteConcept) -> None:
|
|
784
|
+
"""Process a concrete concept"""
|
|
785
|
+
Util.debug(f"Process concrete concept -> {c}")
|
|
786
|
+
current_datatype: OWLDatatype = OWLDatatype(self.iri(c))
|
|
787
|
+
self.datatypes[str(c)] = current_datatype
|
|
788
|
+
|
|
789
|
+
specific: str = self._get_concrete_concept_specifics(c)
|
|
790
|
+
|
|
791
|
+
int_datatype: OWLDatatype = OWLDatatype(XSD.integer)
|
|
792
|
+
greater_than: OWLDatatypeRestriction = OWLDatatypeRestriction(
|
|
793
|
+
int_datatype,
|
|
794
|
+
[
|
|
795
|
+
OWLFacet(
|
|
796
|
+
OWLFacet.MIN_INCLUSIVE,
|
|
797
|
+
OWLLiteral(Literal(str(c.k1), datatype=XSD.decimal)),
|
|
798
|
+
)
|
|
799
|
+
],
|
|
800
|
+
)
|
|
801
|
+
less_than: OWLDatatypeRestriction = OWLDatatypeRestriction(
|
|
802
|
+
int_datatype,
|
|
803
|
+
[
|
|
804
|
+
OWLFacet(
|
|
805
|
+
OWLFacet.MAX_INCLUSIVE,
|
|
806
|
+
OWLLiteral(Literal(str(c.k2), datatype=XSD.decimal)),
|
|
807
|
+
)
|
|
808
|
+
],
|
|
809
|
+
)
|
|
810
|
+
unit_interval: OWLDataIntersectionOf = OWLDataIntersectionOf(
|
|
811
|
+
[greater_than, less_than]
|
|
812
|
+
)
|
|
813
|
+
definition: OWLDatatypeDefinition = OWLDatatypeDefinition(
|
|
814
|
+
current_datatype, unit_interval
|
|
815
|
+
)
|
|
816
|
+
self.ontology.add_axiom(OWLDeclaration(current_datatype))
|
|
817
|
+
self.ontology.add_axiom(definition)
|
|
818
|
+
|
|
819
|
+
annotation: str = (
|
|
820
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.DATATYPE.get_str_value()}">\n'
|
|
821
|
+
f'\t<{FuzzyOWL2Keyword.DATATYPE.get_tag_name()} {FuzzyOWL2Keyword.TYPE.get_str_value()}="{specific}"/>\n'
|
|
822
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
823
|
+
)
|
|
824
|
+
self.add_entity_annotation(annotation, current_datatype)
|
|
825
|
+
|
|
826
|
+
def _get_concrete_concept_specifics(self, c: FuzzyConcreteConcept) -> str:
|
|
827
|
+
"""Get concrete concept specific parameters"""
|
|
828
|
+
if isinstance(c, CrispConcreteConcept):
|
|
829
|
+
return f'{FuzzyOWL2Keyword.CRISP.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
830
|
+
elif isinstance(c, LeftConcreteConcept):
|
|
831
|
+
return f'{FuzzyOWL2Keyword.LEFT_SHOULDER.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
832
|
+
elif isinstance(c, RightConcreteConcept):
|
|
833
|
+
return f'{FuzzyOWL2Keyword.RIGHT_SHOULDER.get_str_value()}" {FuzzyOWL2Keyword.A.get_str_value()}="{c.a}" {FuzzyOWL2Keyword.B.get_str_value()}="{c.b}'
|
|
834
|
+
elif isinstance(c, TriangularConcreteConcept):
|
|
835
|
+
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}'
|
|
836
|
+
elif isinstance(c, TrapezoidalConcreteConcept):
|
|
837
|
+
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}'
|
|
838
|
+
return ""
|
|
839
|
+
|
|
840
|
+
def _process_modifier(self, mod: Modifier) -> None:
|
|
841
|
+
"""Process a modifier"""
|
|
842
|
+
Util.debug(f"Process modifier -> {mod}")
|
|
843
|
+
if isinstance(mod, LinearModifier):
|
|
844
|
+
annotation: str = (
|
|
845
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.MODIFIER.get_str_value()}">\n'
|
|
846
|
+
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'
|
|
847
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
848
|
+
)
|
|
849
|
+
elif isinstance(mod, TriangularModifier):
|
|
850
|
+
annotation: str = (
|
|
851
|
+
f'<{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()} {FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()}="{FuzzyOWL2Keyword.MODIFIER.get_str_value()}">\n'
|
|
852
|
+
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'
|
|
853
|
+
f"</{FuzzyOWL2Keyword.FUZZY_OWL_2.get_str_value()}>"
|
|
854
|
+
)
|
|
855
|
+
else:
|
|
856
|
+
raise ValueError(f"Unknown modifier type: {type(mod)}")
|
|
857
|
+
|
|
858
|
+
current_datatype: OWLDatatype = OWLDatatype(self.iri(mod))
|
|
859
|
+
self.modifiers[str(mod)] = current_datatype
|
|
860
|
+
self.ontology.add_axiom(OWLDeclaration(current_datatype))
|
|
861
|
+
self.add_entity_annotation(annotation, current_datatype)
|
|
862
|
+
|
|
863
|
+
def _process_assertion(self, ass: Assertion) -> None:
|
|
864
|
+
Util.debug(f"Process assertion -> {ass}")
|
|
865
|
+
i: OWLNamedIndividual = self.get_individual(str(ass.get_individual()))
|
|
866
|
+
c: OWLClassExpression = self.get_class(ass.get_concept())
|
|
867
|
+
deg: Degree = ass.get_lower_limit()
|
|
868
|
+
if deg.is_number_not_one():
|
|
869
|
+
new_ann: set[OWLAnnotation] = self.get_annotations_for_axiom(deg)
|
|
870
|
+
axiom: OWLClassAssertion = OWLClassAssertion(c, i, list(new_ann))
|
|
871
|
+
else:
|
|
872
|
+
axiom: OWLClassAssertion = OWLClassAssertion(c, i)
|
|
873
|
+
self.ontology.add_axiom(axiom)
|
|
874
|
+
|
|
875
|
+
def _process_individual(self, ind: Individual) -> None:
|
|
876
|
+
Util.debug(f"Process individual -> {ind}")
|
|
877
|
+
i: OWLClassExpression = self.get_individual(str(ind))
|
|
878
|
+
for a in ind.role_relations.values():
|
|
879
|
+
for rel in a:
|
|
880
|
+
r: typing.Union[OWLDataProperty, OWLObjectProperty] = (
|
|
881
|
+
self.get_object_property(rel.get_role_name())
|
|
882
|
+
) # Retrieve or create the object property
|
|
883
|
+
i2: OWLNamedIndividual = self.get_individual(
|
|
884
|
+
str(rel.get_object_individual())
|
|
885
|
+
) # Retrieve or create the related individual
|
|
886
|
+
|
|
887
|
+
deg: Degree = rel.get_degree()
|
|
888
|
+
if isinstance(r, OWLObjectProperty):
|
|
889
|
+
factory_call: typing.Callable = OWLObjectPropertyAssertion
|
|
890
|
+
else:
|
|
891
|
+
factory_call: typing.Callable = OWLDataPropertyAssertion
|
|
892
|
+
if deg.is_number_not_one(): # If the degree is not 1
|
|
893
|
+
# Create annotations
|
|
894
|
+
new_annotations: set[OWLAnnotation] = (
|
|
895
|
+
self.get_annotations_for_axiom(deg)
|
|
896
|
+
)
|
|
897
|
+
axiom: typing.Union[
|
|
898
|
+
OWLObjectPropertyAssertion, OWLDataPropertyAssertion
|
|
899
|
+
] = factory_call(r, i, i2, new_annotations)
|
|
900
|
+
else:
|
|
901
|
+
axiom: typing.Union[
|
|
902
|
+
OWLObjectPropertyAssertion, OWLDataPropertyAssertion
|
|
903
|
+
] = factory_call(r, i, i2)
|
|
904
|
+
self.ontology.add_axiom(axiom)
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
def main():
|
|
908
|
+
if len(sys.argv) != 3:
|
|
909
|
+
Util.error(
|
|
910
|
+
"Error. Use: python fuzzydl_to_owl2.py <fuzzyDLOntology> <Owl2Ontology>",
|
|
911
|
+
file=sys.stderr,
|
|
912
|
+
)
|
|
913
|
+
sys.exit(-1)
|
|
914
|
+
|
|
915
|
+
converter = FuzzydlToOwl2(sys.argv[1], sys.argv[2])
|
|
916
|
+
converter.run()
|
|
917
|
+
|
|
918
|
+
|
|
919
|
+
if __name__ == "__main__":
|
|
920
|
+
main()
|