fuzzy-dl-owl2 1.0.7__py3-none-any.whl → 1.0.9__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/__init__.py +2 -1
- fuzzy_dl_owl2/fuzzydl/assertion/assertion.py +1 -0
- fuzzy_dl_owl2/fuzzydl/assertion/atomic_assertion.py +2 -0
- fuzzy_dl_owl2/fuzzydl/classification_node.py +64 -0
- fuzzy_dl_owl2/fuzzydl/concept/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/concept/atomic_concept.py +1 -1
- fuzzy_dl_owl2/fuzzydl/concept/choquet_integral.py +6 -0
- fuzzy_dl_owl2/fuzzydl/concept/concept.py +8 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/crisp_concrete_concept.py +1 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_concrete_concept.py +1 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +12 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/left_concrete_concept.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/linear_concrete_concept.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/modified_concrete_concept.py +4 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/right_concrete_concept.py +2 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +1 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/triangular_concrete_concept.py +2 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/linearly_modified_concept.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/modified_concept.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/triangularly_modified_concept.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/negated_nominal.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +8 -0
- fuzzy_dl_owl2/fuzzydl/concept/qowa_concept.py +4 -0
- fuzzy_dl_owl2/fuzzydl/concept/quasi_sugeno_integral.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/sigma_concept.py +71 -0
- fuzzy_dl_owl2/fuzzydl/concept/sigma_count.py +56 -0
- fuzzy_dl_owl2/fuzzydl/concept/sugeno_integral.py +4 -0
- fuzzy_dl_owl2/fuzzydl/concept_equivalence.py +5 -0
- fuzzy_dl_owl2/fuzzydl/concrete_feature.py +6 -0
- fuzzy_dl_owl2/fuzzydl/domain_axiom.py +3 -0
- fuzzy_dl_owl2/fuzzydl/feature_function.py +3 -0
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +169 -27
- fuzzy_dl_owl2/fuzzydl/general_concept_inclusion.py +6 -0
- fuzzy_dl_owl2/fuzzydl/individual/created_individual.py +41 -2
- fuzzy_dl_owl2/fuzzydl/individual/individual.py +14 -0
- fuzzy_dl_owl2/fuzzydl/individual/representative_individual.py +9 -0
- fuzzy_dl_owl2/fuzzydl/knowledge_base.py +2033 -249
- fuzzy_dl_owl2/fuzzydl/label.py +18 -10
- fuzzy_dl_owl2/fuzzydl/milp/expression.py +33 -23
- fuzzy_dl_owl2/fuzzydl/milp/inequation.py +8 -0
- fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +720 -22
- fuzzy_dl_owl2/fuzzydl/milp/show_variables_helper.py +82 -0
- fuzzy_dl_owl2/fuzzydl/milp/solution.py +23 -0
- fuzzy_dl_owl2/fuzzydl/milp/variable.py +7 -0
- fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +3 -0
- fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +21 -0
- fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +48 -7
- fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +7 -0
- fuzzy_dl_owl2/fuzzydl/query/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +80 -1
- fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +2 -0
- fuzzy_dl_owl2/fuzzydl/query/classification_query.py +26 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +2 -1
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +4 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +6 -2
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +2 -0
- fuzzy_dl_owl2/fuzzydl/query/instance_query.py +5 -0
- fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +12 -2
- fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +6 -1
- fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +7 -1
- fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +6 -1
- fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +15 -1
- fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +4 -1
- fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +6 -1
- fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +7 -1
- fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +5 -1
- fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +17 -1
- fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +47 -7
- fuzzy_dl_owl2/fuzzydl/query/query.py +5 -2
- fuzzy_dl_owl2/fuzzydl/query/related_query.py +8 -1
- fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +17 -0
- fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +5 -0
- fuzzy_dl_owl2/fuzzydl/range_axiom.py +4 -0
- fuzzy_dl_owl2/fuzzydl/relation.py +5 -0
- fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +2 -0
- fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +3 -0
- fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +6 -1
- fuzzy_dl_owl2/fuzzydl/util/config_reader.py +17 -27
- fuzzy_dl_owl2/fuzzydl/util/constants.py +100 -0
- fuzzy_dl_owl2-1.0.9.dist-info/METADATA +848 -0
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/RECORD +83 -79
- fuzzy_dl_owl2-1.0.7.dist-info/METADATA +0 -408
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/LICENSE +0 -0
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/WHEEL +0 -0
|
@@ -10,6 +10,7 @@ from .exception import *
|
|
|
10
10
|
from .feature_function import FeatureFunction
|
|
11
11
|
from .general_concept_inclusion import GeneralConceptInclusion
|
|
12
12
|
from .individual import *
|
|
13
|
+
from .classification_node import ClassificationNode
|
|
13
14
|
from .knowledge_base import KnowledgeBase
|
|
14
15
|
from .label import Label
|
|
15
16
|
from .modifier import *
|
|
@@ -20,4 +21,4 @@ from .range_axiom import RangeAxiom
|
|
|
20
21
|
from .relation import Relation
|
|
21
22
|
from .restriction import *
|
|
22
23
|
from .role_parent_with_degree import RoleParentWithDegree
|
|
23
|
-
from .fuzzydl_to_owl2 import FuzzydlToOwl2
|
|
24
|
+
from .fuzzydl_to_owl2 import FuzzydlToOwl2
|
|
@@ -6,7 +6,9 @@ from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
|
|
|
6
6
|
|
|
7
7
|
class AtomicAssertion:
|
|
8
8
|
def __init__(self, c: Concept, degree: Degree) -> None:
|
|
9
|
+
# Atomic concept
|
|
9
10
|
self.c: Concept = c
|
|
11
|
+
# Lower bound degree
|
|
10
12
|
self.degree: Degree = degree
|
|
11
13
|
|
|
12
14
|
def get_concept_name(self) -> str:
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ClassificationNode:
|
|
5
|
+
EQUIVALENT_NAMES: set[str] = set()
|
|
6
|
+
INPUT_EDGES: dict[typing.Self, float] = dict()
|
|
7
|
+
OUTPUT_EDGES: dict[typing.Self, float] = dict()
|
|
8
|
+
|
|
9
|
+
def __init__(self, name: str) -> None:
|
|
10
|
+
ClassificationNode.EQUIVALENT_NAMES.add(name)
|
|
11
|
+
|
|
12
|
+
def is_thing(self) -> bool:
|
|
13
|
+
return self.has_name("*top*")
|
|
14
|
+
|
|
15
|
+
def is_nothing(self) -> bool:
|
|
16
|
+
return self.has_name("*bottom*")
|
|
17
|
+
|
|
18
|
+
def add_input_edge(self, node: typing.Self, n: float) -> None:
|
|
19
|
+
ClassificationNode.INPUT_EDGES[node] = n
|
|
20
|
+
|
|
21
|
+
def add_ouput_edge(self, node: typing.Self, n: float) -> None:
|
|
22
|
+
ClassificationNode.OUTPUT_EDGES[node] = n
|
|
23
|
+
|
|
24
|
+
def remove_input_edge(self, node: typing.Self, n: float) -> None:
|
|
25
|
+
value: typing.Optional[float] = ClassificationNode.INPUT_EDGES.get(node)
|
|
26
|
+
if value is not None and value <= n:
|
|
27
|
+
del ClassificationNode.INPUT_EDGES[node]
|
|
28
|
+
|
|
29
|
+
def remove_ouput_edge(self, node: typing.Self, n: float) -> None:
|
|
30
|
+
value: typing.Optional[float] = ClassificationNode.OUTPUT_EDGES.get(node)
|
|
31
|
+
if value is not None and value <= n:
|
|
32
|
+
del ClassificationNode.OUTPUT_EDGES[node]
|
|
33
|
+
|
|
34
|
+
def has_name(self, name: str) -> bool:
|
|
35
|
+
for s in ClassificationNode.EQUIVALENT_NAMES:
|
|
36
|
+
if s == name:
|
|
37
|
+
return True
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
def add_label(self, c: str) -> None:
|
|
41
|
+
ClassificationNode.EQUIVALENT_NAMES.add(c)
|
|
42
|
+
|
|
43
|
+
def get_output_edges() -> dict[typing.Self, float]:
|
|
44
|
+
return ClassificationNode.OUTPUT_EDGES
|
|
45
|
+
|
|
46
|
+
def get_immediate_successors() -> set[typing.Self]:
|
|
47
|
+
return set(ClassificationNode.INPUT_EDGES.keys())
|
|
48
|
+
|
|
49
|
+
def get_immediate_predecessors() -> set[typing.Self]:
|
|
50
|
+
return set(ClassificationNode.OUTPUT_EDGES.keys())
|
|
51
|
+
|
|
52
|
+
def get_full_name(self) -> str:
|
|
53
|
+
if len(ClassificationNode.EQUIVALENT_NAMES) == 1:
|
|
54
|
+
return str(self)
|
|
55
|
+
return f"{{{ ' '.join(name for name in ClassificationNode.EQUIVALENT_NAMES) }}}"
|
|
56
|
+
|
|
57
|
+
def __hash__(self) -> int:
|
|
58
|
+
return hash(str(self))
|
|
59
|
+
|
|
60
|
+
def __repr__(self) -> str:
|
|
61
|
+
return str(self)
|
|
62
|
+
|
|
63
|
+
def __str__(self) -> str:
|
|
64
|
+
return list(ClassificationNode.EQUIVALENT_NAMES)[0]
|
|
@@ -11,3 +11,5 @@ from .weighted_max_concept import WeightedMaxConcept
|
|
|
11
11
|
from .weighted_min_concept import WeightedMinConcept
|
|
12
12
|
from .weighted_sum_concept import WeightedSumConcept
|
|
13
13
|
from .weighted_sum_zero_concept import WeightedSumZeroConcept
|
|
14
|
+
from .sigma_concept import SigmaConcept
|
|
15
|
+
from .sigma_count import SigmaCount
|
|
@@ -12,6 +12,10 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class ChoquetIntegral(Concept, HasWeightedConceptsInterface):
|
|
15
|
+
"""
|
|
16
|
+
Choquet integral concept.
|
|
17
|
+
"""
|
|
18
|
+
|
|
15
19
|
def __init__(self, weights: list[float], concepts: list[Concept]) -> None:
|
|
16
20
|
Concept.__init__(self, ConceptType.CHOQUET_INTEGRAL)
|
|
17
21
|
HasWeightedConceptsInterface.__init__(self, weights, concepts)
|
|
@@ -22,6 +26,8 @@ class ChoquetIntegral(Concept, HasWeightedConceptsInterface):
|
|
|
22
26
|
"Error: The number of weights and the number of concepts should be the same"
|
|
23
27
|
)
|
|
24
28
|
self.name: str = str(self)
|
|
29
|
+
else:
|
|
30
|
+
self.weights = list()
|
|
25
31
|
|
|
26
32
|
def clone(self) -> typing.Self:
|
|
27
33
|
return ChoquetIntegral(self.weights[:], [c for c in self.concepts])
|
|
@@ -116,6 +116,9 @@ class Thing(ABC):
|
|
|
116
116
|
def get_atomic_concepts(self) -> set[typing.Self]:
|
|
117
117
|
return self.compute_atomic_concepts()
|
|
118
118
|
|
|
119
|
+
def get_atomic_concepts_names(self) -> set[str]:
|
|
120
|
+
return set([str(concept) for concept in self.compute_atomic_concepts()])
|
|
121
|
+
|
|
119
122
|
@abstractmethod
|
|
120
123
|
def get_roles(self) -> set[str]:
|
|
121
124
|
pass
|
|
@@ -163,14 +166,19 @@ class Thing(ABC):
|
|
|
163
166
|
|
|
164
167
|
|
|
165
168
|
class Concept(Thing):
|
|
169
|
+
# Used to create new concepts
|
|
166
170
|
SPECIAL_STRING = "@"
|
|
171
|
+
# Default prefix for new individual names.
|
|
167
172
|
DEFAULT_NAME = f"Concept{SPECIAL_STRING}"
|
|
173
|
+
# Number of new concepts
|
|
168
174
|
num_new_concepts = 1
|
|
169
175
|
|
|
170
176
|
def __init__(
|
|
171
177
|
self, c_type: ConceptType = ConceptType.ATOMIC, name: str = ""
|
|
172
178
|
) -> None:
|
|
179
|
+
# Type of the concept
|
|
173
180
|
self._type: ConceptType = c_type
|
|
181
|
+
# Name of the concept
|
|
174
182
|
self._name: str = name
|
|
175
183
|
|
|
176
184
|
@property
|
|
@@ -9,6 +9,7 @@ from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class CrispConcreteConcept(FuzzyConcreteConcept):
|
|
12
|
+
"""Concrete concept defined with a crisp interval."""
|
|
12
13
|
|
|
13
14
|
def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
|
|
14
15
|
super().__init__(name)
|
|
@@ -12,6 +12,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class FuzzyConcreteConcept(Concept, ABC):
|
|
15
|
+
"""Fuzzy concrete concept defined with an explicit membership function."""
|
|
15
16
|
|
|
16
17
|
def __init__(self, name: str) -> None:
|
|
17
18
|
super().__init__(ConceptType.CONCRETE, name)
|
|
@@ -12,7 +12,11 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class TriangularFuzzyNumber(TriangularConcreteConcept):
|
|
15
|
+
"""Fuzzy number defined with a triangular function."""
|
|
16
|
+
|
|
17
|
+
# Lower bound of the range of the fuzzy numbers.
|
|
15
18
|
K1: float = float("-inf")
|
|
19
|
+
# Upper bound of the range of the fuzzy numbers.
|
|
16
20
|
K2: float = float("inf")
|
|
17
21
|
|
|
18
22
|
@typing.overload
|
|
@@ -41,18 +45,24 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
|
|
|
41
45
|
|
|
42
46
|
@staticmethod
|
|
43
47
|
def add(t1: typing.Self, t2: typing.Self) -> typing.Self:
|
|
48
|
+
"""
|
|
49
|
+
Adds two triangular fuzzy numbers.
|
|
50
|
+
"""
|
|
44
51
|
return t1 + t2
|
|
45
52
|
|
|
46
53
|
@staticmethod
|
|
47
54
|
def minus(t1: typing.Self, t2: typing.Self) -> typing.Self:
|
|
55
|
+
"""Subtracts two triangular fuzzy numbers."""
|
|
48
56
|
return t1 - t2
|
|
49
57
|
|
|
50
58
|
@staticmethod
|
|
51
59
|
def times(t1: typing.Self, t2: typing.Self) -> typing.Self:
|
|
60
|
+
"""Multiplies two triangular fuzzy numbers."""
|
|
52
61
|
return t1 * t2
|
|
53
62
|
|
|
54
63
|
@staticmethod
|
|
55
64
|
def divided_by(t1: typing.Self, t2: typing.Self) -> typing.Self:
|
|
65
|
+
"""Divides two triangular fuzzy numbers."""
|
|
56
66
|
return t1 / t2
|
|
57
67
|
|
|
58
68
|
@staticmethod
|
|
@@ -62,6 +72,7 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
|
|
|
62
72
|
|
|
63
73
|
@staticmethod
|
|
64
74
|
def has_defined_range() -> bool:
|
|
75
|
+
"""Checks if the range of the fuzzy numbers has been defined."""
|
|
65
76
|
return TriangularFuzzyNumber.K1 != float("-inf")
|
|
66
77
|
|
|
67
78
|
def clone(self) -> typing.Self:
|
|
@@ -71,6 +82,7 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
|
|
|
71
82
|
return True
|
|
72
83
|
|
|
73
84
|
def get_best_non_fuzzy_performance(self) -> float:
|
|
85
|
+
"""Gets the Best Non fuzzy Performance (BNP) of the fuzzy number."""
|
|
74
86
|
return Util.round((self.a + self.b + self.c) / 3.0)
|
|
75
87
|
|
|
76
88
|
def is_number(self) -> bool:
|
|
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class LeftConcreteConcept(FuzzyConcreteConcept):
|
|
13
|
+
"""
|
|
14
|
+
Fuzzy concrete concept defined with a left shoulder function
|
|
15
|
+
"""
|
|
13
16
|
|
|
14
17
|
def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
|
|
15
18
|
super().__init__(name)
|
|
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class LinearConcreteConcept(FuzzyConcreteConcept):
|
|
13
|
+
"""
|
|
14
|
+
Fuzzy concrete concept defined with a left shoulder function
|
|
15
|
+
"""
|
|
13
16
|
|
|
14
17
|
def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
|
|
15
18
|
super().__init__(name)
|
|
@@ -10,6 +10,10 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class ModifiedConcreteConcept(FuzzyConcreteConcept):
|
|
13
|
+
"""
|
|
14
|
+
Modified concrete concept.
|
|
15
|
+
"""
|
|
16
|
+
|
|
13
17
|
def __init__(self, name: str, modifier: Modifier, f: FuzzyConcreteConcept) -> None:
|
|
14
18
|
super().__init__(name)
|
|
15
19
|
self.k1: float = 0.0
|
|
@@ -11,6 +11,8 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
11
11
|
|
|
12
12
|
class RightConcreteConcept(FuzzyConcreteConcept):
|
|
13
13
|
|
|
14
|
+
"""Fuzzy concrete concept defined with a right shoulder function."""
|
|
15
|
+
|
|
14
16
|
def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
|
|
15
17
|
super().__init__(name)
|
|
16
18
|
if a > b:
|
|
@@ -10,6 +10,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class TrapezoidalConcreteConcept(FuzzyConcreteConcept):
|
|
13
|
+
"""Fuzzy concrete concept defined with a trapezoidal function."""
|
|
13
14
|
|
|
14
15
|
def __init__(
|
|
15
16
|
self, name: str, k1: float, k2: float, a: float, b: float, c: float, d: float
|
|
@@ -12,6 +12,8 @@ from fuzzy_dl_owl2.fuzzydl.exception.fuzzy_ontology_exception import (
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class TriangularConcreteConcept(FuzzyConcreteConcept):
|
|
15
|
+
"""Fuzzy concrete concept defined with a triangular function."""
|
|
16
|
+
|
|
15
17
|
def __init__(
|
|
16
18
|
self, name: str, k1: float, k2: float, a: float, b: float, c: float
|
|
17
19
|
) -> None:
|
|
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LinearlyModifiedConcept(ModifiedConcept):
|
|
12
|
+
"""
|
|
13
|
+
Fuzzy concept modified with a linear modifier
|
|
14
|
+
"""
|
|
12
15
|
|
|
13
16
|
def __init__(self, c: Concept, mod: Modifier) -> None:
|
|
14
17
|
super().__init__(c, mod)
|
|
@@ -13,6 +13,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
class ModifiedConcept(Concept, HasConceptInterface, ABC):
|
|
16
|
+
"""
|
|
17
|
+
Modified fuzzy concept.
|
|
18
|
+
"""
|
|
16
19
|
|
|
17
20
|
def __init__(self, c: Concept, mod: Modifier) -> None:
|
|
18
21
|
Concept.__init__(self, ConceptType.MODIFIED)
|
|
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class TriangularlyModifiedConcept(ModifiedConcept):
|
|
12
|
+
|
|
13
|
+
"""Fuzzy concept modified with a triangular modifier."""
|
|
14
|
+
|
|
12
15
|
def __init__(self, c: Concept, mod: Modifier) -> None:
|
|
13
16
|
super().__init__(c, mod)
|
|
14
17
|
|
|
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class NegatedNominal(Concept):
|
|
12
|
+
"""
|
|
13
|
+
Negated nominal concept. Only used in range restrictions for the moment.
|
|
14
|
+
"""
|
|
12
15
|
|
|
13
16
|
def __init__(self, ind_name: str) -> None:
|
|
14
17
|
super().__init__(ConceptType.ATOMIC)
|
|
@@ -12,6 +12,10 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType, FuzzyLogic
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class OperatorConcept(Concept, HasConceptsInterface):
|
|
15
|
+
"""
|
|
16
|
+
Defines a logic operator concept defined as AND, OR or NOT of concepts.
|
|
17
|
+
"""
|
|
18
|
+
|
|
15
19
|
AND_OPERATORS: list[ConceptType] = [
|
|
16
20
|
ConceptType.AND,
|
|
17
21
|
ConceptType.GOEDEL_AND,
|
|
@@ -262,6 +266,10 @@ class OperatorConcept(Concept, HasConceptsInterface):
|
|
|
262
266
|
def is_not_zadeh_implies(op: Concept) -> bool:
|
|
263
267
|
return OperatorConcept.is_not_type(op, ConceptType.ZADEH_IMPLIES)
|
|
264
268
|
|
|
269
|
+
@staticmethod
|
|
270
|
+
def is_not_sigma_concept(op: Concept) -> bool:
|
|
271
|
+
return OperatorConcept.is_not_type(op, ConceptType.SIGMA_CONCEPT)
|
|
272
|
+
|
|
265
273
|
def is_concrete(self) -> bool:
|
|
266
274
|
if OperatorConcept.is_not_concrete(self) or OperatorConcept.is_not_fuzzy_number(
|
|
267
275
|
self
|
|
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class QsugenoIntegral(SugenoIntegral):
|
|
13
|
+
"""
|
|
14
|
+
Quasi Sugeno integral concept.
|
|
15
|
+
"""
|
|
13
16
|
|
|
14
17
|
def __init__(self, weights: list[float], concepts: list[Concept]) -> None:
|
|
15
18
|
super().__init__(weights, concepts)
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
4
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
|
|
5
|
+
FuzzyConcreteConcept,
|
|
6
|
+
)
|
|
7
|
+
from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
|
|
8
|
+
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
9
|
+
from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class SigmaConcept(Concept):
|
|
13
|
+
"""Sigma-count concept."""
|
|
14
|
+
|
|
15
|
+
def __init__(
|
|
16
|
+
self,
|
|
17
|
+
concept: Concept,
|
|
18
|
+
role: str,
|
|
19
|
+
individuals: list[Individual],
|
|
20
|
+
concrete_concept: FuzzyConcreteConcept,
|
|
21
|
+
) -> None:
|
|
22
|
+
super().__init__(ConceptType.SIGMA_CONCEPT, "")
|
|
23
|
+
self.concept: Concept = concept
|
|
24
|
+
self.role: str = role
|
|
25
|
+
self.individuals: list[Individual] = individuals
|
|
26
|
+
self.concrete_concept: FuzzyConcreteConcept = concrete_concept
|
|
27
|
+
self.name: str = self.compute_name()
|
|
28
|
+
|
|
29
|
+
def get_individuals(self) -> list[Individual]:
|
|
30
|
+
return self.individuals
|
|
31
|
+
|
|
32
|
+
def get_concept(self) -> Concept:
|
|
33
|
+
return self.concept
|
|
34
|
+
|
|
35
|
+
def get_role(self) -> str:
|
|
36
|
+
return self.role
|
|
37
|
+
|
|
38
|
+
def get_fuzzy_concept(self) -> FuzzyConcreteConcept:
|
|
39
|
+
return self.concrete_concept
|
|
40
|
+
|
|
41
|
+
def clone(self) -> typing.Self:
|
|
42
|
+
return SigmaConcept(
|
|
43
|
+
self.concept.clone(),
|
|
44
|
+
self.role,
|
|
45
|
+
[i.clone() for i in self.individuals],
|
|
46
|
+
self.concrete_concept.clone(),
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def compute_atomic_concepts(self) -> set[Concept]:
|
|
50
|
+
return set()
|
|
51
|
+
|
|
52
|
+
def get_roles(self) -> set[str]:
|
|
53
|
+
return set()
|
|
54
|
+
|
|
55
|
+
def replace(self, a: Concept, c: Concept) -> Concept:
|
|
56
|
+
return self
|
|
57
|
+
|
|
58
|
+
def compute_name(self) -> str | None:
|
|
59
|
+
return f"(sigma-count {self.role} {self.concept} {{{' '.join(map(str, self.individuals))}}} {self.concrete_concept})"
|
|
60
|
+
|
|
61
|
+
def __neg__(self) -> Concept:
|
|
62
|
+
return OperatorConcept.not_(self)
|
|
63
|
+
|
|
64
|
+
def __and__(self, value: typing.Self) -> typing.Self:
|
|
65
|
+
return OperatorConcept.and_(self, value)
|
|
66
|
+
|
|
67
|
+
def __or__(self, value: typing.Self) -> typing.Self:
|
|
68
|
+
return OperatorConcept.or_(self, value)
|
|
69
|
+
|
|
70
|
+
def __hash__(self) -> int:
|
|
71
|
+
return hash(str(self))
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import typing
|
|
2
|
+
|
|
3
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
4
|
+
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
5
|
+
from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class SigmaCount:
|
|
9
|
+
"""Sigma-count pending tasks."""
|
|
10
|
+
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
var: Variable,
|
|
14
|
+
ind: Individual,
|
|
15
|
+
inds: list[Individual],
|
|
16
|
+
role: str,
|
|
17
|
+
concept: Concept,
|
|
18
|
+
) -> None:
|
|
19
|
+
self.variable: Variable = var
|
|
20
|
+
self.individual: Individual = ind
|
|
21
|
+
self.individuals: list[Individual] = inds
|
|
22
|
+
self.role: str = role
|
|
23
|
+
self.concept: Concept = concept
|
|
24
|
+
|
|
25
|
+
def clone(self) -> typing.Self:
|
|
26
|
+
return SigmaCount(
|
|
27
|
+
self.variable.clone(),
|
|
28
|
+
self.individual.clone(),
|
|
29
|
+
[i.clone() for i in self.individuals],
|
|
30
|
+
self.role,
|
|
31
|
+
self.concept.clone(),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
def get_variable(self) -> Variable:
|
|
35
|
+
return self.variable
|
|
36
|
+
|
|
37
|
+
def get_individual(self) -> Individual:
|
|
38
|
+
return self.individual
|
|
39
|
+
|
|
40
|
+
def get_individuals(self) -> list[Individual]:
|
|
41
|
+
return self.individuals
|
|
42
|
+
|
|
43
|
+
def get_role(self) -> str:
|
|
44
|
+
return self.role
|
|
45
|
+
|
|
46
|
+
def get_concept(self) -> Concept:
|
|
47
|
+
return self.concept
|
|
48
|
+
|
|
49
|
+
def __hash__(self) -> int:
|
|
50
|
+
return hash(str(self))
|
|
51
|
+
|
|
52
|
+
def __repr__(self) -> str:
|
|
53
|
+
return str(self)
|
|
54
|
+
|
|
55
|
+
def __str__(self) -> str:
|
|
56
|
+
return f"sigma-count({self.variable}, {self.individual}, {self.individuals}, {self.role}, {self.concept})"
|
|
@@ -14,6 +14,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class SugenoIntegral(Concept, HasWeightedConceptsInterface):
|
|
17
|
+
"""Sugeno integral concept."""
|
|
17
18
|
|
|
18
19
|
@typing.overload
|
|
19
20
|
def __init__(self) -> None: ...
|
|
@@ -48,6 +49,9 @@ class SugenoIntegral(Concept, HasWeightedConceptsInterface):
|
|
|
48
49
|
"Error: The number of weights and the number of concepts should be the same"
|
|
49
50
|
)
|
|
50
51
|
self.name = self.compute_name()
|
|
52
|
+
else:
|
|
53
|
+
self.weights: list[float] = []
|
|
54
|
+
|
|
51
55
|
|
|
52
56
|
def clone(self) -> typing.Self:
|
|
53
57
|
return SugenoIntegral(self.weights[:], [c for c in self.concepts])
|
|
@@ -6,8 +6,13 @@ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class ConceptEquivalence:
|
|
9
|
+
"""
|
|
10
|
+
Concept equivalence axiom
|
|
11
|
+
"""
|
|
9
12
|
def __init__(self, c1: Concept, c2: Concept) -> None:
|
|
13
|
+
# First concept
|
|
10
14
|
self.c1: Concept = c1
|
|
15
|
+
# Second concept
|
|
11
16
|
self.c2: Concept = c2
|
|
12
17
|
|
|
13
18
|
def clone(self) -> typing.Self:
|
|
@@ -41,7 +41,9 @@ class ConcreteFeature:
|
|
|
41
41
|
|
|
42
42
|
def __concrete_feature_init_1(self, name: str) -> None:
|
|
43
43
|
self.name: str = name
|
|
44
|
+
# Lower bound for the range
|
|
44
45
|
self.k1: typing.Optional[typing.Union[float, int]] = None
|
|
46
|
+
# Upper bound for the range
|
|
45
47
|
self.k2: typing.Optional[typing.Union[float, int]] = None
|
|
46
48
|
self.type: ConcreteFeatureType = ConcreteFeatureType.STRING
|
|
47
49
|
|
|
@@ -52,13 +54,17 @@ class ConcreteFeature:
|
|
|
52
54
|
|
|
53
55
|
def __concrete_feature_init_3(self, name: str, k1: int, k2: int) -> None:
|
|
54
56
|
self.__concrete_feature_init_1(name)
|
|
57
|
+
# Lower bound for the range
|
|
55
58
|
self.k1: typing.Optional[typing.Union[float, int]] = k1
|
|
59
|
+
# Upper bound for the range
|
|
56
60
|
self.k2: typing.Optional[typing.Union[float, int]] = k2
|
|
57
61
|
self.type: ConcreteFeatureType = ConcreteFeatureType.INTEGER
|
|
58
62
|
|
|
59
63
|
def __concrete_feature_init_4(self, name: str, k1: float, k2: float) -> None:
|
|
60
64
|
self.__concrete_feature_init_1(name)
|
|
65
|
+
# Lower bound for the range
|
|
61
66
|
self.k1: typing.Optional[typing.Union[float, int]] = k1
|
|
67
|
+
# Upper bound for the range
|
|
62
68
|
self.k2: typing.Optional[typing.Union[float, int]] = k2
|
|
63
69
|
self.type: ConcreteFeatureType = ConcreteFeatureType.REAL
|
|
64
70
|
|
|
@@ -12,6 +12,7 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import FeatureFunctionType
|
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
class FeatureFunction:
|
|
15
|
+
"""Function involving several features."""
|
|
15
16
|
|
|
16
17
|
@typing.overload
|
|
17
18
|
def __init__(self, feature: typing.Self) -> None: ...
|
|
@@ -105,6 +106,7 @@ class FeatureFunction:
|
|
|
105
106
|
return self.n
|
|
106
107
|
|
|
107
108
|
def get_features(self) -> set[str]:
|
|
109
|
+
"""Gets an array of features that take part in the function."""
|
|
108
110
|
features: set[str] = set()
|
|
109
111
|
if self.type == FeatureFunctionType.ATOMIC:
|
|
110
112
|
features.add(self.feature)
|
|
@@ -121,6 +123,7 @@ class FeatureFunction:
|
|
|
121
123
|
def to_expression(
|
|
122
124
|
self, a: Individual, milp: MILPHelper
|
|
123
125
|
) -> typing.Optional[Expression]:
|
|
126
|
+
"""Gets an array of features that take part in the function."""
|
|
124
127
|
if self.type == FeatureFunctionType.ATOMIC:
|
|
125
128
|
# Get the filler "b" for feature(a)
|
|
126
129
|
rel_set: list[Relation] = a.role_relations.get(self.feature)
|