fuzzy-dl-owl2 1.0.5__py3-none-any.whl → 1.0.7__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/fuzzydl/feature_function.py +9 -3
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +204 -66
- fuzzy_dl_owl2/fuzzydl/knowledge_base.py +13 -5
- fuzzy_dl_owl2/fuzzydl/milp/expression.py +13 -2
- fuzzy_dl_owl2/fuzzydl/milp/inequation.py +12 -0
- fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +694 -54
- fuzzy_dl_owl2/fuzzydl/milp/term.py +4 -1
- fuzzy_dl_owl2/fuzzydl/util/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/util/config_reader.py +44 -2
- fuzzy_dl_owl2/fuzzydl/util/constants.py +5 -6
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +25 -17
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_property.py +7 -1
- fuzzy_dl_owl2/fuzzyowl2/parser/__init__.py +2 -1
- fuzzy_dl_owl2/fuzzyowl2/parser/owl2_parser.py +7 -7
- fuzzy_dl_owl2/fuzzyowl2/parser/owl2_xml_parser.py +226 -0
- fuzzy_dl_owl2/fuzzyowl2/util/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzyowl2/util/constants.py +138 -52
- fuzzy_dl_owl2/fuzzyowl2/util/fuzzy_xml.py +107 -0
- {fuzzy_dl_owl2-1.0.5.dist-info → fuzzy_dl_owl2-1.0.7.dist-info}/METADATA +72 -4
- {fuzzy_dl_owl2-1.0.5.dist-info → fuzzy_dl_owl2-1.0.7.dist-info}/RECORD +22 -20
- {fuzzy_dl_owl2-1.0.5.dist-info → fuzzy_dl_owl2-1.0.7.dist-info}/LICENSE +0 -0
- {fuzzy_dl_owl2-1.0.5.dist-info → fuzzy_dl_owl2-1.0.7.dist-info}/WHEEL +0 -0
|
@@ -64,11 +64,14 @@ class Term:
|
|
|
64
64
|
def __eq__(self, term: typing.Self) -> bool:
|
|
65
65
|
if not isinstance(term, Term):
|
|
66
66
|
return False
|
|
67
|
-
return self.var == term.var
|
|
67
|
+
return self.var == term.var and self.coeff == term.coeff
|
|
68
68
|
|
|
69
69
|
def __ne__(self, term: typing.Self) -> bool:
|
|
70
70
|
return not (self == term)
|
|
71
71
|
|
|
72
|
+
def __hash__(self) -> int:
|
|
73
|
+
return hash(str(self))
|
|
74
|
+
|
|
72
75
|
def __repr__(self) -> str:
|
|
73
76
|
return str(self)
|
|
74
77
|
|
|
@@ -1,19 +1,42 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import configparser
|
|
4
|
+
import enum
|
|
4
5
|
import math
|
|
5
6
|
|
|
7
|
+
from fuzzy_dl_owl2.fuzzydl.util import constants
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MILPProvider(enum.StrEnum):
|
|
11
|
+
GUROBI = enum.auto()
|
|
12
|
+
MIP = enum.auto()
|
|
13
|
+
# SCIPY = enum.auto()
|
|
14
|
+
PULP = enum.auto()
|
|
15
|
+
PULP_GLPK = enum.auto()
|
|
16
|
+
PULP_HIGHS = enum.auto()
|
|
17
|
+
PULP_CPLEX = enum.auto()
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def from_str(value: str) -> MILPProvider:
|
|
21
|
+
try:
|
|
22
|
+
return MILPProvider(value.lower())
|
|
23
|
+
except ValueError:
|
|
24
|
+
raise ValueError(
|
|
25
|
+
f"Invalid MILP provider: {value}. Valid options are: {list(MILPProvider)}"
|
|
26
|
+
)
|
|
27
|
+
|
|
6
28
|
|
|
7
29
|
class ConfigReader:
|
|
8
30
|
ANYWHERE_DOUBLE_BLOCKING: bool = True
|
|
9
31
|
ANYWHERE_SIMPLE_BLOCKING: bool = True
|
|
10
|
-
RELAX_MILP: bool = False
|
|
11
32
|
DEBUG_PRINT: bool = True
|
|
12
33
|
EPSILON: float = 0.001
|
|
13
34
|
MAX_INDIVIDUALS: int = -1
|
|
14
35
|
NUMBER_DIGITS: int = 2
|
|
15
36
|
OPTIMIZATIONS: int = 1
|
|
16
37
|
RULE_ACYCLIC_TBOXES: bool = True
|
|
38
|
+
OWL_ANNOTATION_LABEL: str = "fuzzyLabel"
|
|
39
|
+
MILP_PROVIDER: MILPProvider = MILPProvider.GUROBI
|
|
17
40
|
|
|
18
41
|
@staticmethod
|
|
19
42
|
def load_parameters(config_file: str, args: list[str]) -> None:
|
|
@@ -33,13 +56,32 @@ class ConfigReader:
|
|
|
33
56
|
# "author": False,
|
|
34
57
|
# }
|
|
35
58
|
|
|
36
|
-
ConfigReader.RELAX_MILP = config.getboolean("DEFAULT", "relaxMilp")
|
|
37
59
|
ConfigReader.DEBUG_PRINT = config.getboolean("DEFAULT", "debugPrint")
|
|
38
60
|
ConfigReader.EPSILON = config.getfloat("DEFAULT", "epsilon")
|
|
39
61
|
ConfigReader.MAX_INDIVIDUALS = config.getint("DEFAULT", "maxIndividuals")
|
|
62
|
+
ConfigReader.OWL_ANNOTATION_LABEL = config.get(
|
|
63
|
+
"DEFAULT", "owlAnnotationLabel"
|
|
64
|
+
)
|
|
65
|
+
ConfigReader.MILP_PROVIDER = MILPProvider(
|
|
66
|
+
config.get("DEFAULT", "milpProvider").lower()
|
|
67
|
+
)
|
|
40
68
|
ConfigReader.NUMBER_DIGITS = int(
|
|
41
69
|
round(abs(math.log10(ConfigReader.EPSILON) - 1.0))
|
|
42
70
|
)
|
|
71
|
+
if ConfigReader.MILP_PROVIDER in [
|
|
72
|
+
MILPProvider.MIP,
|
|
73
|
+
MILPProvider.PULP,
|
|
74
|
+
]:
|
|
75
|
+
constants.MAXVAL = (1 << 31) - 1
|
|
76
|
+
constants.MAXVAL2 = constants.MAXVAL * 2
|
|
77
|
+
elif ConfigReader.MILP_PROVIDER in [
|
|
78
|
+
MILPProvider.PULP_GLPK,
|
|
79
|
+
MILPProvider.PULP_HIGHS,
|
|
80
|
+
MILPProvider.PULP_CPLEX,
|
|
81
|
+
# MILPProvider.SCIPY,
|
|
82
|
+
]:
|
|
83
|
+
constants.MAXVAL = (1 << 28) - 1
|
|
84
|
+
constants.MAXVAL2 = constants.MAXVAL * 2
|
|
43
85
|
|
|
44
86
|
if ConfigReader.DEBUG_PRINT:
|
|
45
87
|
print(f"Debugging mode = {ConfigReader.DEBUG_PRINT}")
|
|
@@ -4,7 +4,6 @@ import re
|
|
|
4
4
|
import typing
|
|
5
5
|
|
|
6
6
|
import pyparsing as pp
|
|
7
|
-
from gurobipy import GRB
|
|
8
7
|
|
|
9
8
|
SEPARATOR: str = "-" * 25
|
|
10
9
|
STAR_SEPARATOR: str = "*" * 25
|
|
@@ -239,10 +238,10 @@ class InequalityType(enum.StrEnum):
|
|
|
239
238
|
|
|
240
239
|
|
|
241
240
|
class VariableType(enum.StrEnum):
|
|
242
|
-
BINARY =
|
|
243
|
-
CONTINUOUS =
|
|
244
|
-
INTEGER =
|
|
245
|
-
SEMI_CONTINUOUS =
|
|
241
|
+
BINARY = enum.auto()
|
|
242
|
+
CONTINUOUS = enum.auto()
|
|
243
|
+
INTEGER = enum.auto()
|
|
244
|
+
SEMI_CONTINUOUS = enum.auto()
|
|
246
245
|
|
|
247
246
|
def __repr__(self) -> str:
|
|
248
247
|
return self.name
|
|
@@ -421,5 +420,5 @@ class FuzzyLogic(enum.StrEnum):
|
|
|
421
420
|
|
|
422
421
|
|
|
423
422
|
KNOWLEDGE_BASE_SEMANTICS: FuzzyLogic = FuzzyLogic.CLASSICAL
|
|
424
|
-
MAXVAL: float = 2.147483647e12
|
|
423
|
+
MAXVAL: float = ((1 << 31) - 1) * 1000 # 2.147483647e12
|
|
425
424
|
MAXVAL2: float = MAXVAL * 2
|
|
@@ -35,7 +35,7 @@ from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_sum_concept import WeightedSumCo
|
|
|
35
35
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_sum_zero_concept import (
|
|
36
36
|
WeightedSumZeroConcept,
|
|
37
37
|
)
|
|
38
|
-
from fuzzy_dl_owl2.fuzzyowl2.parser.
|
|
38
|
+
from fuzzy_dl_owl2.fuzzyowl2.parser.owl2_xml_parser import FuzzyOwl2XMLParser
|
|
39
39
|
from pyowl2.abstracts.annotation_value import OWLAnnotationValue
|
|
40
40
|
from pyowl2.abstracts.axiom import OWLAxiom
|
|
41
41
|
from pyowl2.abstracts.class_expression import OWLClassExpression
|
|
@@ -146,6 +146,8 @@ from pyowl2.individual.anonymous_individual import OWLAnonymousIndividual
|
|
|
146
146
|
from pyowl2.literal.literal import OWLLiteral
|
|
147
147
|
from pyowl2.ontology import OWLOntology
|
|
148
148
|
|
|
149
|
+
from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
|
|
150
|
+
|
|
149
151
|
|
|
150
152
|
class FuzzyOwl2(object):
|
|
151
153
|
POS_INFINITY: float = 10000.0
|
|
@@ -166,7 +168,7 @@ class FuzzyOwl2(object):
|
|
|
166
168
|
self.processed_axioms: set[str] = set()
|
|
167
169
|
self.ontologies: set[OWLOntology] = set()
|
|
168
170
|
|
|
169
|
-
|
|
171
|
+
FuzzyOwl2XMLParser.load_config()
|
|
170
172
|
|
|
171
173
|
self.ontology_path = input_file
|
|
172
174
|
self.ontology_iri = IRI(Namespace(base_iri))
|
|
@@ -174,7 +176,7 @@ class FuzzyOwl2(object):
|
|
|
174
176
|
self.ontology_iri, self.ontology_path, OWL1_annotations=True
|
|
175
177
|
)
|
|
176
178
|
self.fuzzy_label: OWLAnnotationProperty = OWLAnnotationProperty(
|
|
177
|
-
IRI(self.ontology_iri.namespace,
|
|
179
|
+
IRI(self.ontology_iri.namespace, ConfigReader.OWL_ANNOTATION_LABEL)
|
|
178
180
|
)
|
|
179
181
|
self.ontologies.add(self.ontology)
|
|
180
182
|
# self.ontologies.update(self.manager.getImportsClosure(self.ontology))
|
|
@@ -200,9 +202,13 @@ class FuzzyOwl2(object):
|
|
|
200
202
|
if annotation.annotation_property != self.fuzzy_label:
|
|
201
203
|
continue
|
|
202
204
|
value: OWLAnnotationValue = annotation.annotation_value
|
|
203
|
-
annotation_str: str = str(value)
|
|
205
|
+
annotation_str: str = str(value)
|
|
204
206
|
Util.debug(f"Annotation for ontology -> {annotation_str}")
|
|
205
|
-
|
|
207
|
+
logic: typing.Optional[str] = FuzzyOwl2XMLParser.parse_string(
|
|
208
|
+
annotation_str
|
|
209
|
+
)
|
|
210
|
+
Util.debug(f"Parsed annotation -> {logic}")
|
|
211
|
+
self.write_fuzzy_logic(logic)
|
|
206
212
|
|
|
207
213
|
def __get_facets(self, name: str) -> list[float]:
|
|
208
214
|
facets: list[float] = [float("-inf"), float("inf")]
|
|
@@ -282,13 +288,14 @@ class FuzzyOwl2(object):
|
|
|
282
288
|
f"Error: There are {len(annotations)} datatype annotations for {datatype}"
|
|
283
289
|
)
|
|
284
290
|
annotation: OWLAnnotation = list(annotations)[0].annotation_value
|
|
285
|
-
annotation_str: str = str(annotation)
|
|
291
|
+
annotation_str: str = str(annotation)
|
|
286
292
|
Util.debug(f"Annotation for {datatype} -> {annotation_str}")
|
|
287
293
|
datatype_name: str = self.get_short_name(datatype)
|
|
288
294
|
facets: list[OWLFacet] = self.__get_facets(datatype_name)
|
|
289
295
|
c: typing.Union[ConceptDefinition, FuzzyModifier] = (
|
|
290
|
-
|
|
296
|
+
FuzzyOwl2XMLParser.parse_string(annotation_str)
|
|
291
297
|
)
|
|
298
|
+
Util.debug(f"Parsed annotation -> {c}")
|
|
292
299
|
if isinstance(c, FuzzyDatatype):
|
|
293
300
|
c.set_min_value(facets[0])
|
|
294
301
|
c.set_max_value(facets[1])
|
|
@@ -330,12 +337,12 @@ class FuzzyOwl2(object):
|
|
|
330
337
|
f"Error: There are {len(annotations)} class annotations for {cls}"
|
|
331
338
|
)
|
|
332
339
|
annotation: OWLAnnotation = list(annotations)[0].annotation_value
|
|
333
|
-
annotation_str: str = str(annotation)
|
|
340
|
+
annotation_str: str = str(annotation)
|
|
334
341
|
Util.debug(f"Annotation for concept {cls} -> {annotation_str}")
|
|
335
|
-
concept: ConceptDefinition =
|
|
342
|
+
concept: ConceptDefinition = FuzzyOwl2XMLParser.parse_string(
|
|
336
343
|
annotation_str
|
|
337
|
-
)
|
|
338
|
-
Util.debug(f"
|
|
344
|
+
)
|
|
345
|
+
Util.debug(f"Parsed annotation -> {concept}")
|
|
339
346
|
name: str = self.get_short_name(cls)
|
|
340
347
|
if isinstance(concept, ModifiedConcept):
|
|
341
348
|
mod_name: str = concept.get_fuzzy_modifier()
|
|
@@ -401,11 +408,12 @@ class FuzzyOwl2(object):
|
|
|
401
408
|
f"Error: There are {len(annotations)} property annotations for {property}"
|
|
402
409
|
)
|
|
403
410
|
annotation: OWLAnnotation = list(annotations)[0].annotation_value
|
|
404
|
-
annotation_str: str = str(annotation)
|
|
411
|
+
annotation_str: str = str(annotation)
|
|
405
412
|
Util.debug(f"Annotation for property {property} -> {annotation_str}")
|
|
406
413
|
prop: typing.Optional[ModifiedProperty] = (
|
|
407
|
-
|
|
408
|
-
)
|
|
414
|
+
FuzzyOwl2XMLParser.parse_string(annotation_str)
|
|
415
|
+
)
|
|
416
|
+
Util.debug(f"Parsed annotation -> {prop}")
|
|
409
417
|
if prop is None:
|
|
410
418
|
return
|
|
411
419
|
if not isinstance(prop, ModifiedProperty):
|
|
@@ -428,10 +436,10 @@ class FuzzyOwl2(object):
|
|
|
428
436
|
f"Error: There are {len(annotations)} annotations for axiom {axiom}."
|
|
429
437
|
)
|
|
430
438
|
annotation: OWLAnnotation = list(annotations)[0].annotation_value
|
|
431
|
-
annotation_str: str = str(annotation)
|
|
439
|
+
annotation_str: str = str(annotation)
|
|
432
440
|
Util.debug(f"Annotation for degree -> {annotation_str}")
|
|
433
|
-
deg: float =
|
|
434
|
-
Util.debug(f"
|
|
441
|
+
deg: float = FuzzyOwl2XMLParser.parse_string(annotation_str)
|
|
442
|
+
Util.debug(f"Parsed annotation -> {deg}")
|
|
435
443
|
if not isinstance(deg, constants.NUMBER):
|
|
436
444
|
raise ValueError
|
|
437
445
|
return deg
|
|
@@ -4,7 +4,7 @@ from fuzzy_dl_owl2.fuzzyowl2.owl_types.fuzzy_property import FuzzyProperty
|
|
|
4
4
|
class ModifiedProperty(FuzzyProperty):
|
|
5
5
|
|
|
6
6
|
def __init__(self, mod: str, prop: str) -> None:
|
|
7
|
-
super.__init__()
|
|
7
|
+
super().__init__()
|
|
8
8
|
self._mod: str = mod
|
|
9
9
|
self._prop: str = prop
|
|
10
10
|
|
|
@@ -13,3 +13,9 @@ class ModifiedProperty(FuzzyProperty):
|
|
|
13
13
|
|
|
14
14
|
def get_property(self) -> str:
|
|
15
15
|
return self._prop
|
|
16
|
+
|
|
17
|
+
def __repr__(self) -> str:
|
|
18
|
+
return str(self)
|
|
19
|
+
|
|
20
|
+
def __str__(self) -> str:
|
|
21
|
+
return f"({self.get_fuzzy_modifier()}, {self.get_property()})"
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
from .owl2_parser import *
|
|
1
|
+
# from .owl2_parser import *
|
|
2
|
+
from .owl2_xml_parser import *
|
|
@@ -6,11 +6,7 @@ import typing
|
|
|
6
6
|
|
|
7
7
|
import pyparsing as pp
|
|
8
8
|
|
|
9
|
-
from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
|
|
10
9
|
from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
|
|
11
|
-
from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
|
|
12
|
-
from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
13
|
-
from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import TriangularModifier
|
|
14
10
|
from fuzzy_dl_owl2.fuzzydl.query.query import Query
|
|
15
11
|
from fuzzy_dl_owl2.fuzzydl.util import utils
|
|
16
12
|
from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
|
|
@@ -18,14 +14,17 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
18
14
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.choquet_concept import ChoquetConcept
|
|
19
15
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.concept_definition import ConceptDefinition
|
|
20
16
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.fuzzy_datatype import FuzzyDatatype
|
|
17
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.fuzzy_modifier import FuzzyModifier
|
|
21
18
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.fuzzy_nominal_concept import FuzzyNominalConcept
|
|
22
19
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.left_shoulder_function import (
|
|
23
20
|
LeftShoulderFunction,
|
|
24
21
|
)
|
|
25
22
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.linear_function import LinearFunction
|
|
23
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.linear_modifier import LinearModifier
|
|
26
24
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.modified_concept import ModifiedConcept
|
|
27
25
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.modified_property import ModifiedProperty
|
|
28
26
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.owa_concept import OwaConcept
|
|
27
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.qowa_concept import QowaConcept
|
|
29
28
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.quasi_sugeno_concept import QsugenoConcept
|
|
30
29
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.right_shoulder_function import (
|
|
31
30
|
RightShoulderFunction,
|
|
@@ -33,6 +32,7 @@ from fuzzy_dl_owl2.fuzzyowl2.owl_types.right_shoulder_function import (
|
|
|
33
32
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.sugeno_concept import SugenoConcept
|
|
34
33
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.trapezoidal_function import TrapezoidalFunction
|
|
35
34
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.triangular_function import TriangularFunction
|
|
35
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.triangular_modifer import TriangularModifier
|
|
36
36
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_concept import WeightedConcept
|
|
37
37
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_max_concept import WeightedMaxConcept
|
|
38
38
|
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_min_concept import WeightedMinConcept
|
|
@@ -66,13 +66,13 @@ def _parse_fuzzy_datatype(tokens: pp.ParseResults) -> FuzzyDatatype:
|
|
|
66
66
|
return tokens
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
def _parse_modifier_function(tokens: pp.ParseResults) ->
|
|
69
|
+
def _parse_modifier_function(tokens: pp.ParseResults) -> FuzzyModifier:
|
|
70
70
|
Util.debug(f"_parse_modifier_function -> {tokens}")
|
|
71
71
|
list_tokens: list = tokens.as_list()
|
|
72
72
|
if list_tokens[0] == FuzzyOWL2Keyword.LINEAR:
|
|
73
|
-
return LinearModifier(
|
|
73
|
+
return LinearModifier(list_tokens[1])
|
|
74
74
|
elif list_tokens[0] == FuzzyOWL2Keyword.TRIANGULAR:
|
|
75
|
-
return TriangularModifier(
|
|
75
|
+
return TriangularModifier(list_tokens[1], list_tokens[2], list_tokens[3])
|
|
76
76
|
return tokens
|
|
77
77
|
|
|
78
78
|
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import traceback
|
|
5
|
+
import typing
|
|
6
|
+
from xml.etree import ElementTree
|
|
7
|
+
|
|
8
|
+
import pyparsing as pp
|
|
9
|
+
|
|
10
|
+
from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
|
|
11
|
+
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
12
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.choquet_concept import ChoquetConcept
|
|
13
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.fuzzy_nominal_concept import FuzzyNominalConcept
|
|
14
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.left_shoulder_function import (
|
|
15
|
+
LeftShoulderFunction,
|
|
16
|
+
)
|
|
17
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.linear_function import LinearFunction
|
|
18
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.linear_modifier import LinearModifier
|
|
19
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.modified_concept import ModifiedConcept
|
|
20
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.modified_property import ModifiedProperty
|
|
21
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.owa_concept import OwaConcept
|
|
22
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.qowa_concept import QowaConcept
|
|
23
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.quasi_sugeno_concept import QsugenoConcept
|
|
24
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.right_shoulder_function import (
|
|
25
|
+
RightShoulderFunction,
|
|
26
|
+
)
|
|
27
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.sugeno_concept import SugenoConcept
|
|
28
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.trapezoidal_function import TrapezoidalFunction
|
|
29
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.triangular_function import TriangularFunction
|
|
30
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.triangular_modifer import TriangularModifier
|
|
31
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_concept import WeightedConcept
|
|
32
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_max_concept import WeightedMaxConcept
|
|
33
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_min_concept import WeightedMinConcept
|
|
34
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_sum_concept import WeightedSumConcept
|
|
35
|
+
from fuzzy_dl_owl2.fuzzyowl2.owl_types.weighted_sum_zero_concept import (
|
|
36
|
+
WeightedSumZeroConcept,
|
|
37
|
+
)
|
|
38
|
+
from fuzzy_dl_owl2.fuzzyowl2.util.constants import FuzzyOWL2Keyword
|
|
39
|
+
from fuzzy_dl_owl2.fuzzyowl2.util.fuzzy_xml import FuzzyXML
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class FuzzyOwl2XMLParser(object):
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def get_caseless_attrib(attrib: dict[str, str], key: str) -> typing.Optional[str]:
|
|
46
|
+
keys = [k for k in attrib if k.lower() == key.lower()]
|
|
47
|
+
return attrib.get(keys[0]) if len(keys) > 0 else None
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def parse_string(
|
|
51
|
+
instring: str,
|
|
52
|
+
) -> pp.ParseResults:
|
|
53
|
+
root: ElementTree.Element = ElementTree.fromstring(instring)
|
|
54
|
+
Util.debug(f"XML PARSER -> {FuzzyXML.to_str(root)}")
|
|
55
|
+
assert root.tag == FuzzyOWL2Keyword.FUZZY_OWL_2
|
|
56
|
+
|
|
57
|
+
annotation_type: str = root.attrib.get(
|
|
58
|
+
FuzzyOWL2Keyword.FUZZY_TYPE.get_str_value()
|
|
59
|
+
)
|
|
60
|
+
if annotation_type == FuzzyOWL2Keyword.CONCEPT:
|
|
61
|
+
child = root.find(FuzzyOWL2Keyword.CONCEPT.get_tag_name())
|
|
62
|
+
concept_type = child.attrib.get(FuzzyOWL2Keyword.TYPE.get_str_value())
|
|
63
|
+
if concept_type == FuzzyOWL2Keyword.MODIFIED:
|
|
64
|
+
return ModifiedConcept(
|
|
65
|
+
child.attrib.get(FuzzyOWL2Keyword.MODIFIER.get_str_value()),
|
|
66
|
+
child.attrib.get(FuzzyOWL2Keyword.BASE.get_str_value()),
|
|
67
|
+
)
|
|
68
|
+
elif concept_type == FuzzyOWL2Keyword.WEIGHTED:
|
|
69
|
+
return WeightedConcept(
|
|
70
|
+
float(
|
|
71
|
+
child.attrib.get(FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value())
|
|
72
|
+
),
|
|
73
|
+
child.attrib.get(FuzzyOWL2Keyword.BASE.get_str_value()),
|
|
74
|
+
)
|
|
75
|
+
elif concept_type in (
|
|
76
|
+
FuzzyOWL2Keyword.WEIGHTED_MINIMUM,
|
|
77
|
+
FuzzyOWL2Keyword.WEIGHTED_MAXIMUM,
|
|
78
|
+
FuzzyOWL2Keyword.WEIGHTED_SUM,
|
|
79
|
+
FuzzyOWL2Keyword.WEIGHTED_SUMZERO,
|
|
80
|
+
):
|
|
81
|
+
wc: list[WeightedConcept] = [
|
|
82
|
+
WeightedConcept(
|
|
83
|
+
float(
|
|
84
|
+
inner_child.attrib.get(
|
|
85
|
+
FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value()
|
|
86
|
+
)
|
|
87
|
+
),
|
|
88
|
+
inner_child.attrib.get(FuzzyOWL2Keyword.BASE.get_str_value()),
|
|
89
|
+
)
|
|
90
|
+
for inner_child in child
|
|
91
|
+
if inner_child.tag == FuzzyOWL2Keyword.CONCEPT.get_tag_name()
|
|
92
|
+
and inner_child.attrib.get(FuzzyOWL2Keyword.TYPE.get_str_value())
|
|
93
|
+
== FuzzyOWL2Keyword.WEIGHTED
|
|
94
|
+
]
|
|
95
|
+
if concept_type == FuzzyOWL2Keyword.WEIGHTED_MAXIMUM:
|
|
96
|
+
return WeightedMaxConcept(wc)
|
|
97
|
+
elif concept_type == FuzzyOWL2Keyword.WEIGHTED_MINIMUM:
|
|
98
|
+
return WeightedMinConcept(wc)
|
|
99
|
+
elif concept_type == FuzzyOWL2Keyword.WEIGHTED_SUM:
|
|
100
|
+
return WeightedSumConcept(wc)
|
|
101
|
+
elif concept_type == FuzzyOWL2Keyword.WEIGHTED_SUMZERO:
|
|
102
|
+
return WeightedSumZeroConcept(wc)
|
|
103
|
+
elif concept_type in (
|
|
104
|
+
FuzzyOWL2Keyword.OWA,
|
|
105
|
+
FuzzyOWL2Keyword.CHOQUET,
|
|
106
|
+
FuzzyOWL2Keyword.SUGENO,
|
|
107
|
+
FuzzyOWL2Keyword.QUASI_SUGENO,
|
|
108
|
+
):
|
|
109
|
+
weights: list[float] = [
|
|
110
|
+
float(weight.text)
|
|
111
|
+
for weight in child.find(
|
|
112
|
+
FuzzyOWL2Keyword.WEIGHTS.get_tag_name()
|
|
113
|
+
).findall(FuzzyOWL2Keyword.WEIGHT.get_tag_name())
|
|
114
|
+
]
|
|
115
|
+
concepts: list[str] = [
|
|
116
|
+
name.text
|
|
117
|
+
for name in child.find(
|
|
118
|
+
FuzzyOWL2Keyword.CONCEPT_NAMES.get_tag_name()
|
|
119
|
+
).findall(FuzzyOWL2Keyword.NAME.get_tag_name())
|
|
120
|
+
]
|
|
121
|
+
if concept_type == FuzzyOWL2Keyword.OWA:
|
|
122
|
+
return OwaConcept(weights, concepts)
|
|
123
|
+
elif concept_type == FuzzyOWL2Keyword.CHOQUET:
|
|
124
|
+
return ChoquetConcept(weights, concepts)
|
|
125
|
+
elif concept_type == FuzzyOWL2Keyword.SUGENO:
|
|
126
|
+
return SugenoConcept(weights, concepts)
|
|
127
|
+
elif concept_type == FuzzyOWL2Keyword.QUASI_SUGENO:
|
|
128
|
+
return QsugenoConcept(weights, concepts)
|
|
129
|
+
elif concept_type == FuzzyOWL2Keyword.Q_OWA:
|
|
130
|
+
quantifier = child.attrib.get(
|
|
131
|
+
FuzzyOWL2Keyword.QUANTIFIER.get_str_value()
|
|
132
|
+
)
|
|
133
|
+
concepts: list[str] = [
|
|
134
|
+
name.text
|
|
135
|
+
for name in child.find(
|
|
136
|
+
FuzzyOWL2Keyword.CONCEPT_NAMES.get_tag_name()
|
|
137
|
+
).findall(FuzzyOWL2Keyword.NAME.get_tag_name())
|
|
138
|
+
]
|
|
139
|
+
return QowaConcept(quantifier, concepts)
|
|
140
|
+
elif concept_type == FuzzyOWL2Keyword.NOMINAL:
|
|
141
|
+
return FuzzyNominalConcept(
|
|
142
|
+
float(
|
|
143
|
+
child.attrib.get(FuzzyOWL2Keyword.DEGREE_DEF.get_str_value())
|
|
144
|
+
),
|
|
145
|
+
child.attrib.get(FuzzyOWL2Keyword.INDIVIDUAL.get_str_value()),
|
|
146
|
+
)
|
|
147
|
+
elif annotation_type == FuzzyOWL2Keyword.DATATYPE:
|
|
148
|
+
child = root.find(FuzzyOWL2Keyword.DATATYPE.get_tag_name())
|
|
149
|
+
datatype_type = child.attrib.get(FuzzyOWL2Keyword.TYPE.get_str_value())
|
|
150
|
+
|
|
151
|
+
if datatype_type == FuzzyOWL2Keyword.LEFT_SHOULDER:
|
|
152
|
+
return LeftShoulderFunction(
|
|
153
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
154
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
155
|
+
)
|
|
156
|
+
elif datatype_type == FuzzyOWL2Keyword.RIGHT_SHOULDER:
|
|
157
|
+
return RightShoulderFunction(
|
|
158
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
159
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
160
|
+
)
|
|
161
|
+
elif datatype_type == FuzzyOWL2Keyword.LINEAR:
|
|
162
|
+
return LinearFunction(
|
|
163
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
164
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
165
|
+
)
|
|
166
|
+
elif datatype_type == FuzzyOWL2Keyword.TRIANGULAR:
|
|
167
|
+
return TriangularFunction(
|
|
168
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
169
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
170
|
+
float(child.attrib.get(FuzzyOWL2Keyword.C.get_str_value())),
|
|
171
|
+
)
|
|
172
|
+
elif datatype_type == FuzzyOWL2Keyword.TRAPEZOIDAL:
|
|
173
|
+
return TrapezoidalFunction(
|
|
174
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
175
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
176
|
+
float(child.attrib.get(FuzzyOWL2Keyword.C.get_str_value())),
|
|
177
|
+
float(child.attrib.get(FuzzyOWL2Keyword.D.get_str_value())),
|
|
178
|
+
)
|
|
179
|
+
elif annotation_type == FuzzyOWL2Keyword.MODIFIER:
|
|
180
|
+
child = root.find(FuzzyOWL2Keyword.MODIFIER.get_tag_name())
|
|
181
|
+
mod_type = child.attrib.get(FuzzyOWL2Keyword.TYPE.get_str_value())
|
|
182
|
+
if mod_type == FuzzyOWL2Keyword.LINEAR:
|
|
183
|
+
return LinearModifier(
|
|
184
|
+
float(child.attrib.get(FuzzyOWL2Keyword.C.get_str_value())),
|
|
185
|
+
)
|
|
186
|
+
elif mod_type == FuzzyOWL2Keyword.TRIANGULAR:
|
|
187
|
+
return TriangularModifier(
|
|
188
|
+
float(child.attrib.get(FuzzyOWL2Keyword.A.get_str_value())),
|
|
189
|
+
float(child.attrib.get(FuzzyOWL2Keyword.B.get_str_value())),
|
|
190
|
+
float(child.attrib.get(FuzzyOWL2Keyword.C.get_str_value())),
|
|
191
|
+
)
|
|
192
|
+
elif annotation_type == FuzzyOWL2Keyword.AXIOM:
|
|
193
|
+
child = root.find(FuzzyOWL2Keyword.DEGREE_DEF.get_tag_name())
|
|
194
|
+
return float(
|
|
195
|
+
child.attrib.get(FuzzyOWL2Keyword.DEGREE_VALUE.get_str_value())
|
|
196
|
+
)
|
|
197
|
+
elif annotation_type == FuzzyOWL2Keyword.ONTOLOGY:
|
|
198
|
+
child = root.find(FuzzyOWL2Keyword.FUZZY_LOGIC.get_tag_name())
|
|
199
|
+
return child.attrib.get(FuzzyOWL2Keyword.LOGIC.get_str_value())
|
|
200
|
+
elif annotation_type == FuzzyOWL2Keyword.ROLE:
|
|
201
|
+
child = root.find(FuzzyOWL2Keyword.ROLE.get_tag_name())
|
|
202
|
+
assert (
|
|
203
|
+
child.attrib.get(FuzzyOWL2Keyword.TYPE.get_str_value())
|
|
204
|
+
== FuzzyOWL2Keyword.MODIFIED
|
|
205
|
+
)
|
|
206
|
+
return ModifiedProperty(
|
|
207
|
+
child.attrib.get(FuzzyOWL2Keyword.MODIFIER.get_str_value()),
|
|
208
|
+
child.attrib.get(FuzzyOWL2Keyword.BASE.get_str_value()),
|
|
209
|
+
)
|
|
210
|
+
else:
|
|
211
|
+
raise ValueError
|
|
212
|
+
|
|
213
|
+
@staticmethod
|
|
214
|
+
def load_config(*args) -> None:
|
|
215
|
+
ConfigReader.load_parameters(os.path.join(os.getcwd(), "CONFIG.ini"), args)
|
|
216
|
+
|
|
217
|
+
@staticmethod
|
|
218
|
+
def main(annotation: str, *args) -> typing.Any:
|
|
219
|
+
try:
|
|
220
|
+
FuzzyOwl2XMLParser.load_config(*args)
|
|
221
|
+
return FuzzyOwl2XMLParser.parse_string(annotation)
|
|
222
|
+
except FileNotFoundError as e:
|
|
223
|
+
Util.error(f"Error: File {args[0]} not found.")
|
|
224
|
+
except Exception as e:
|
|
225
|
+
Util.error(e)
|
|
226
|
+
Util.error(traceback.format_exc())
|