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.
Files changed (167) hide show
  1. fuzzy_dl_owl2/__init__.py +2 -0
  2. fuzzy_dl_owl2/fuzzydl/__init__.py +23 -0
  3. fuzzy_dl_owl2/fuzzydl/assertion/__init__.py +2 -0
  4. fuzzy_dl_owl2/fuzzydl/assertion/assertion.py +72 -0
  5. fuzzy_dl_owl2/fuzzydl/assertion/atomic_assertion.py +19 -0
  6. fuzzy_dl_owl2/fuzzydl/concept/__init__.py +13 -0
  7. fuzzy_dl_owl2/fuzzydl/concept/all_some_concept.py +85 -0
  8. fuzzy_dl_owl2/fuzzydl/concept/approximation_concept.py +147 -0
  9. fuzzy_dl_owl2/fuzzydl/concept/atomic_concept.py +91 -0
  10. fuzzy_dl_owl2/fuzzydl/concept/choquet_integral.py +64 -0
  11. fuzzy_dl_owl2/fuzzydl/concept/concept.py +230 -0
  12. fuzzy_dl_owl2/fuzzydl/concept/concrete/__init__.py +10 -0
  13. fuzzy_dl_owl2/fuzzydl/concept/concrete/crisp_concrete_concept.py +60 -0
  14. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_concrete_concept.py +63 -0
  15. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/__init__.py +1 -0
  16. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +127 -0
  17. fuzzy_dl_owl2/fuzzydl/concept/concrete/left_concrete_concept.py +70 -0
  18. fuzzy_dl_owl2/fuzzydl/concept/concrete/linear_concrete_concept.py +70 -0
  19. fuzzy_dl_owl2/fuzzydl/concept/concrete/modified_concrete_concept.py +66 -0
  20. fuzzy_dl_owl2/fuzzydl/concept/concrete/right_concrete_concept.py +70 -0
  21. fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +96 -0
  22. fuzzy_dl_owl2/fuzzydl/concept/concrete/triangular_concrete_concept.py +89 -0
  23. fuzzy_dl_owl2/fuzzydl/concept/ext_threshold_concept.py +77 -0
  24. fuzzy_dl_owl2/fuzzydl/concept/has_value_concept.py +51 -0
  25. fuzzy_dl_owl2/fuzzydl/concept/implies_concept.py +144 -0
  26. fuzzy_dl_owl2/fuzzydl/concept/interface/__init__.py +6 -0
  27. fuzzy_dl_owl2/fuzzydl/concept/interface/has_concept_interface.py +17 -0
  28. fuzzy_dl_owl2/fuzzydl/concept/interface/has_concepts_interface.py +18 -0
  29. fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_concept_interface.py +14 -0
  30. fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_interface.py +15 -0
  31. fuzzy_dl_owl2/fuzzydl/concept/interface/has_value_interface.py +21 -0
  32. fuzzy_dl_owl2/fuzzydl/concept/interface/has_weighted_concepts_interface.py +29 -0
  33. fuzzy_dl_owl2/fuzzydl/concept/modified/__init__.py +3 -0
  34. fuzzy_dl_owl2/fuzzydl/concept/modified/linearly_modified_concept.py +32 -0
  35. fuzzy_dl_owl2/fuzzydl/concept/modified/modified_concept.py +59 -0
  36. fuzzy_dl_owl2/fuzzydl/concept/modified/triangularly_modified_concept.py +33 -0
  37. fuzzy_dl_owl2/fuzzydl/concept/negated_nominal.py +42 -0
  38. fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +707 -0
  39. fuzzy_dl_owl2/fuzzydl/concept/owa_concept.py +57 -0
  40. fuzzy_dl_owl2/fuzzydl/concept/qowa_concept.py +62 -0
  41. fuzzy_dl_owl2/fuzzydl/concept/quasi_sugeno_integral.py +46 -0
  42. fuzzy_dl_owl2/fuzzydl/concept/self_concept.py +45 -0
  43. fuzzy_dl_owl2/fuzzydl/concept/string_concept.py +35 -0
  44. fuzzy_dl_owl2/fuzzydl/concept/sugeno_integral.py +83 -0
  45. fuzzy_dl_owl2/fuzzydl/concept/threshold_concept.py +81 -0
  46. fuzzy_dl_owl2/fuzzydl/concept/truth_concept.py +83 -0
  47. fuzzy_dl_owl2/fuzzydl/concept/value_concept.py +67 -0
  48. fuzzy_dl_owl2/fuzzydl/concept/weighted_concept.py +55 -0
  49. fuzzy_dl_owl2/fuzzydl/concept/weighted_max_concept.py +63 -0
  50. fuzzy_dl_owl2/fuzzydl/concept/weighted_min_concept.py +57 -0
  51. fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_concept.py +62 -0
  52. fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_zero_concept.py +62 -0
  53. fuzzy_dl_owl2/fuzzydl/concept_equivalence.py +20 -0
  54. fuzzy_dl_owl2/fuzzydl/concrete_feature.py +94 -0
  55. fuzzy_dl_owl2/fuzzydl/degree/__init__.py +4 -0
  56. fuzzy_dl_owl2/fuzzydl/degree/degree.py +79 -0
  57. fuzzy_dl_owl2/fuzzydl/degree/degree_expression.py +57 -0
  58. fuzzy_dl_owl2/fuzzydl/degree/degree_numeric.py +57 -0
  59. fuzzy_dl_owl2/fuzzydl/degree/degree_variable.py +54 -0
  60. fuzzy_dl_owl2/fuzzydl/domain_axiom.py +8 -0
  61. fuzzy_dl_owl2/fuzzydl/exception/__init__.py +2 -0
  62. fuzzy_dl_owl2/fuzzydl/exception/fuzzy_ontology_exception.py +4 -0
  63. fuzzy_dl_owl2/fuzzydl/exception/inconsistent_ontology_exception.py +4 -0
  64. fuzzy_dl_owl2/fuzzydl/feature_function.py +148 -0
  65. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +920 -0
  66. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2_java.py +953 -0
  67. fuzzy_dl_owl2/fuzzydl/general_concept_inclusion.py +82 -0
  68. fuzzy_dl_owl2/fuzzydl/individual/__init__.py +3 -0
  69. fuzzy_dl_owl2/fuzzydl/individual/created_individual.py +219 -0
  70. fuzzy_dl_owl2/fuzzydl/individual/individual.py +113 -0
  71. fuzzy_dl_owl2/fuzzydl/individual/representative_individual.py +37 -0
  72. fuzzy_dl_owl2/fuzzydl/knowledge_base.py +9037 -0
  73. fuzzy_dl_owl2/fuzzydl/label.py +32 -0
  74. fuzzy_dl_owl2/fuzzydl/milp/__init__.py +7 -0
  75. fuzzy_dl_owl2/fuzzydl/milp/expression.py +186 -0
  76. fuzzy_dl_owl2/fuzzydl/milp/inequation.py +55 -0
  77. fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +787 -0
  78. fuzzy_dl_owl2/fuzzydl/milp/show_variables_helper.py +151 -0
  79. fuzzy_dl_owl2/fuzzydl/milp/solution.py +45 -0
  80. fuzzy_dl_owl2/fuzzydl/milp/term.py +76 -0
  81. fuzzy_dl_owl2/fuzzydl/milp/variable.py +89 -0
  82. fuzzy_dl_owl2/fuzzydl/modifier/__init__.py +3 -0
  83. fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +76 -0
  84. fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +39 -0
  85. fuzzy_dl_owl2/fuzzydl/modifier/triangular_modifier.py +76 -0
  86. fuzzy_dl_owl2/fuzzydl/parser/ParserConstants.py +406 -0
  87. fuzzy_dl_owl2/fuzzydl/parser/__init__.py +1 -0
  88. fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +2029 -0
  89. fuzzy_dl_owl2/fuzzydl/parser/ebnf.lark +290 -0
  90. fuzzy_dl_owl2/fuzzydl/parser/larkx.py +70 -0
  91. fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +81 -0
  92. fuzzy_dl_owl2/fuzzydl/query/__init__.py +14 -0
  93. fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +50 -0
  94. fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +22 -0
  95. fuzzy_dl_owl2/fuzzydl/query/defuzzify/__init__.py +4 -0
  96. fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +76 -0
  97. fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +19 -0
  98. fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +88 -0
  99. fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +20 -0
  100. fuzzy_dl_owl2/fuzzydl/query/instance_query.py +19 -0
  101. fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +32 -0
  102. fuzzy_dl_owl2/fuzzydl/query/max/__init__.py +5 -0
  103. fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +45 -0
  104. fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +31 -0
  105. fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +45 -0
  106. fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +73 -0
  107. fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +64 -0
  108. fuzzy_dl_owl2/fuzzydl/query/min/__init__.py +5 -0
  109. fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +50 -0
  110. fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +31 -0
  111. fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +57 -0
  112. fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +80 -0
  113. fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +65 -0
  114. fuzzy_dl_owl2/fuzzydl/query/query.py +38 -0
  115. fuzzy_dl_owl2/fuzzydl/query/related_query.py +15 -0
  116. fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +37 -0
  117. fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +20 -0
  118. fuzzy_dl_owl2/fuzzydl/range_axiom.py +7 -0
  119. fuzzy_dl_owl2/fuzzydl/relation.py +47 -0
  120. fuzzy_dl_owl2/fuzzydl/restriction/__init__.py +2 -0
  121. fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +16 -0
  122. fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +34 -0
  123. fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +10 -0
  124. fuzzy_dl_owl2/fuzzydl/util/__init__.py +3 -0
  125. fuzzy_dl_owl2/fuzzydl/util/config_reader.py +56 -0
  126. fuzzy_dl_owl2/fuzzydl/util/constants.py +424 -0
  127. fuzzy_dl_owl2/fuzzydl/util/util.py +73 -0
  128. fuzzy_dl_owl2/fuzzyowl2/__init__.py +5 -0
  129. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +1513 -0
  130. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_java.py +1409 -0
  131. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl.py +917 -0
  132. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl_java.py +956 -0
  133. fuzzy_dl_owl2/fuzzyowl2/owl_types/__init__.py +0 -0
  134. fuzzy_dl_owl2/fuzzyowl2/owl_types/choquet_concept.py +19 -0
  135. fuzzy_dl_owl2/fuzzyowl2/owl_types/concept_definition.py +14 -0
  136. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_datatype.py +22 -0
  137. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_modifier.py +4 -0
  138. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_nominal_concept.py +19 -0
  139. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_property.py +5 -0
  140. fuzzy_dl_owl2/fuzzyowl2/owl_types/left_shoulder_function.py +17 -0
  141. fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_function.py +17 -0
  142. fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_modifier.py +13 -0
  143. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_concept.py +19 -0
  144. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_function.py +17 -0
  145. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_property.py +15 -0
  146. fuzzy_dl_owl2/fuzzyowl2/owl_types/owa_concept.py +19 -0
  147. fuzzy_dl_owl2/fuzzyowl2/owl_types/property_definition.py +10 -0
  148. fuzzy_dl_owl2/fuzzyowl2/owl_types/qowa_concept.py +19 -0
  149. fuzzy_dl_owl2/fuzzyowl2/owl_types/quasi_sugeno_concept.py +21 -0
  150. fuzzy_dl_owl2/fuzzyowl2/owl_types/right_shoulder_function.py +17 -0
  151. fuzzy_dl_owl2/fuzzyowl2/owl_types/sugeno_concept.py +21 -0
  152. fuzzy_dl_owl2/fuzzyowl2/owl_types/trapezoidal_function.py +25 -0
  153. fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_function.py +21 -0
  154. fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_modifer.py +21 -0
  155. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_concept.py +19 -0
  156. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_max_concept.py +15 -0
  157. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_min_concept.py +15 -0
  158. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_concept.py +15 -0
  159. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_zero_concept.py +15 -0
  160. fuzzy_dl_owl2/fuzzyowl2/parser/__init__.py +1 -0
  161. fuzzy_dl_owl2/fuzzyowl2/parser/owl2_parser.py +491 -0
  162. fuzzy_dl_owl2/fuzzyowl2/util/__init__.py +1 -0
  163. fuzzy_dl_owl2/fuzzyowl2/util/constants.py +112 -0
  164. fuzzy_dl_owl2-1.0.0.dist-info/LICENSE +427 -0
  165. fuzzy_dl_owl2-1.0.0.dist-info/METADATA +299 -0
  166. fuzzy_dl_owl2-1.0.0.dist-info/RECORD +167 -0
  167. 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()