fuzzy-dl-owl2 1.0.7__py3-none-any.whl → 1.0.8__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/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 -245
- 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.8.dist-info/METADATA +817 -0
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.8.dist-info}/RECORD +82 -78
- fuzzy_dl_owl2-1.0.7.dist-info/METADATA +0 -408
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.8.dist-info}/LICENSE +0 -0
- {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.8.dist-info}/WHEEL +0 -0
|
@@ -11,13 +11,21 @@ from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
|
|
|
11
11
|
|
|
12
12
|
class ShowVariablesHelper:
|
|
13
13
|
def __init__(self) -> None:
|
|
14
|
+
# For every filler, the list of individuals for which the filler has to be shown
|
|
14
15
|
self.abstract_fillers: dict[str, set[str]] = dict()
|
|
16
|
+
# Show the instances of these concepts
|
|
15
17
|
self.concepts: set[str] = set()
|
|
18
|
+
# For every filler, the list of individuals for which the filler has to be shown
|
|
16
19
|
self.concrete_fillers: dict[str, set[str]] = dict()
|
|
20
|
+
# Show these abstract fillers, for every individual
|
|
17
21
|
self.global_abstract_fillers: set[str] = set()
|
|
22
|
+
# Show these concrete fillers, for every individual
|
|
18
23
|
self.global_concrete_fillers: set[str] = set()
|
|
24
|
+
# Show the membership degree of these individual to every atomic concept
|
|
19
25
|
self.individuals: set[str] = set()
|
|
26
|
+
# For every concrete filler, show the membership degree to these fuzzy concrete concepts
|
|
20
27
|
self.labels_for_fillers: dict[str, list[FuzzyConcreteConcept]] = dict()
|
|
28
|
+
# Show these variables
|
|
21
29
|
self.variables: dict[Variable, str] = dict()
|
|
22
30
|
|
|
23
31
|
def clone(self) -> typing.Self:
|
|
@@ -35,15 +43,19 @@ class ShowVariablesHelper:
|
|
|
35
43
|
return s
|
|
36
44
|
|
|
37
45
|
def get_name(self, var: Variable) -> str:
|
|
46
|
+
"""Gets the name of a variable."""
|
|
38
47
|
return self.variables.get(var)
|
|
39
48
|
|
|
40
49
|
def show_variable(self, var: Variable) -> bool:
|
|
50
|
+
"""Checks whether the variable exists or not."""
|
|
41
51
|
return var in self.variables
|
|
42
52
|
|
|
43
53
|
def add_individual_to_show(self, ind_name: str) -> None:
|
|
54
|
+
"""Shows the value of an individual to every atomic concept."""
|
|
44
55
|
self.individuals.add(ind_name)
|
|
45
56
|
|
|
46
57
|
def show_individuals(self, ind_name: str) -> bool:
|
|
58
|
+
"""Checks whether an individual is marked to be shown or not."""
|
|
47
59
|
return ind_name in self.individuals
|
|
48
60
|
|
|
49
61
|
@typing.overload
|
|
@@ -58,6 +70,7 @@ class ShowVariablesHelper:
|
|
|
58
70
|
) -> None: ...
|
|
59
71
|
|
|
60
72
|
def add_concrete_filler_to_show(self, *args) -> None:
|
|
73
|
+
"""Shows the value of the fillers of a concrete feature."""
|
|
61
74
|
assert len(args) in [1, 2, 3]
|
|
62
75
|
assert isinstance(args[0], str)
|
|
63
76
|
if len(args) == 1:
|
|
@@ -73,11 +86,24 @@ class ShowVariablesHelper:
|
|
|
73
86
|
self.__add_concrete_filler_to_show_3(*args)
|
|
74
87
|
|
|
75
88
|
def __add_concrete_filler_to_show_1(self, f_name: str) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Shows the value of the fillers of a concrete feature.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
f_name (str): Name of the concrete feature.
|
|
94
|
+
"""
|
|
76
95
|
self.global_concrete_fillers.add(f_name)
|
|
77
96
|
if f_name in self.concrete_fillers:
|
|
78
97
|
del self.concrete_fillers[f_name]
|
|
79
98
|
|
|
80
99
|
def __add_concrete_filler_to_show_2(self, f_name: str, ind_name: str) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Shows the value of the fillers of a concrete feature for an individual.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
f_name (str): Name of the concrete feature.
|
|
105
|
+
ind_name (str): Name of the individual.
|
|
106
|
+
"""
|
|
81
107
|
if f_name in self.global_concrete_fillers:
|
|
82
108
|
return
|
|
83
109
|
self.concrete_fillers[f_name] = self.concrete_fillers.get(f_name, set()) | set(
|
|
@@ -87,9 +113,18 @@ class ShowVariablesHelper:
|
|
|
87
113
|
def __add_concrete_filler_to_show_3(
|
|
88
114
|
self, f_name: str, ind_name: str, ar: list[FuzzyConcreteConcept]
|
|
89
115
|
) -> None:
|
|
116
|
+
"""
|
|
117
|
+
Shows the membership degree to some fuzzy concrete concepts (representing linguistic labels of the feature), for the fillers of a concrete feature of an individual.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
f_name (str): Name of the concrete feature.
|
|
121
|
+
ind_name (str): Name of the individual.
|
|
122
|
+
ar (list[FuzzyConcreteConcept]): Array of fuzzy concrete concepts.
|
|
123
|
+
"""
|
|
90
124
|
self.add_concrete_filler_to_show(f_name, ind_name)
|
|
91
125
|
name: str = f"{f_name}({ind_name})"
|
|
92
126
|
aux: list[FuzzyConcreteConcept] = self.get_labels(name)
|
|
127
|
+
# Add labels to be shown
|
|
93
128
|
if len(aux) > 0:
|
|
94
129
|
aux.extend(ar)
|
|
95
130
|
self.labels_for_fillers[name] = aux
|
|
@@ -97,6 +132,7 @@ class ShowVariablesHelper:
|
|
|
97
132
|
self.labels_for_fillers[name] = ar
|
|
98
133
|
|
|
99
134
|
def get_labels(self, var_name: str) -> list[FuzzyConcreteConcept]:
|
|
135
|
+
"""Gets the fuzzy concrete concepts marked to be shown for a variable."""
|
|
100
136
|
return self.labels_for_fillers.get(var_name, [])
|
|
101
137
|
|
|
102
138
|
@typing.overload
|
|
@@ -106,6 +142,7 @@ class ShowVariablesHelper:
|
|
|
106
142
|
def add_abstract_filler_to_show(self, role_name: str, ind_name: str) -> None: ...
|
|
107
143
|
|
|
108
144
|
def add_abstract_filler_to_show(self, *args) -> None:
|
|
145
|
+
"""Shows the membership degree to some atomic concepts of the fillers of an abstract role."""
|
|
109
146
|
assert len(args) in [1, 2]
|
|
110
147
|
assert isinstance(args[0], str)
|
|
111
148
|
if len(args) == 1:
|
|
@@ -115,11 +152,24 @@ class ShowVariablesHelper:
|
|
|
115
152
|
self.__add_abstract_filler_to_show_2(*args)
|
|
116
153
|
|
|
117
154
|
def __add_abstract_filler_to_show_1(self, role_name: str) -> None:
|
|
155
|
+
"""
|
|
156
|
+
Shows the membership degree to some atomic concepts of the fillers of an abstract role.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
role_name (str): Name of the abstract role.
|
|
160
|
+
"""
|
|
118
161
|
self.global_abstract_fillers.add(role_name)
|
|
119
162
|
if role_name in self.abstract_fillers:
|
|
120
163
|
del self.abstract_fillers[role_name]
|
|
121
164
|
|
|
122
165
|
def __add_abstract_filler_to_show_2(self, role_name: str, ind_name: str) -> None:
|
|
166
|
+
"""
|
|
167
|
+
Shows the membership degree to some atomic concepts of the fillers of an abstract role for some individual.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
role_name (str): Name of the abstract role.
|
|
171
|
+
ind_name (str): Name of the individual.
|
|
172
|
+
"""
|
|
123
173
|
if role_name in self.global_abstract_fillers:
|
|
124
174
|
return
|
|
125
175
|
self.abstract_fillers[role_name] = self.abstract_fillers.get(
|
|
@@ -127,25 +177,57 @@ class ShowVariablesHelper:
|
|
|
127
177
|
) | set([ind_name])
|
|
128
178
|
|
|
129
179
|
def show_concrete_fillers(self, f_name: str, ind_name: str) -> bool:
|
|
180
|
+
"""
|
|
181
|
+
Returns whether a given individuals is marked for showing every filler of a concrete feature.
|
|
182
|
+
|
|
183
|
+
Args:
|
|
184
|
+
f_name (str): Name of the concrete feature.
|
|
185
|
+
ind_name (str): Name of the individual.
|
|
186
|
+
"""
|
|
130
187
|
if f_name not in self.global_concrete_fillers:
|
|
131
188
|
hs = self.concrete_fillers.get(f_name)
|
|
132
189
|
return hs is not None and ind_name in hs
|
|
133
190
|
return True
|
|
134
191
|
|
|
135
192
|
def show_abstract_role_fillers(self, role_name: str, ind_name: str) -> bool:
|
|
193
|
+
"""
|
|
194
|
+
Returns whether a given individuals is marked for showing every filler of an abstract role.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
role_name (str): Name of the abstract role.
|
|
198
|
+
ind_name (str): Name of the individual.
|
|
199
|
+
"""
|
|
136
200
|
if role_name not in self.global_abstract_fillers:
|
|
137
201
|
hs = self.abstract_fillers.get(role_name)
|
|
138
202
|
return hs is not None and ind_name in hs
|
|
139
203
|
return True
|
|
140
204
|
|
|
141
205
|
def add_concept_to_show(self, conc_name: str) -> None:
|
|
206
|
+
"""Show membership degree of every instance of an atomic concept."""
|
|
142
207
|
self.concepts.add(conc_name)
|
|
143
208
|
|
|
144
209
|
def show_concepts(self, concept_name: str) -> bool:
|
|
210
|
+
"""
|
|
211
|
+
Returns whether an atomic concept is marked to show the membership degree of every individual.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
concept_name (str): Name of atomic concept.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
bool: true if the concept is marked to be shown; false otherwise.
|
|
218
|
+
"""
|
|
145
219
|
return concept_name in self.concepts
|
|
146
220
|
|
|
147
221
|
def add_variable(self, var: Variable, name_to_show: str) -> None:
|
|
222
|
+
"""
|
|
223
|
+
Add a variable to shown, showing it with a given name.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
var (Variable): A variable.
|
|
227
|
+
name_to_show (str): Name of the variable when shown.
|
|
228
|
+
"""
|
|
148
229
|
self.variables[var] = name_to_show
|
|
149
230
|
|
|
150
231
|
def get_variables(self) -> list[Variable]:
|
|
232
|
+
"""Gets the variables to be shown."""
|
|
151
233
|
return list(self.variables.keys())
|
|
@@ -4,7 +4,9 @@ from fuzzy_dl_owl2.fuzzydl.util import constants
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class Solution:
|
|
7
|
+
# Indicates whether the fuzzy KB is consistent
|
|
7
8
|
CONSISTENT_KB: bool = True
|
|
9
|
+
# Indicates whether the fuzzy KB is inconsistent
|
|
8
10
|
INCONSISTENT_KB: bool = False
|
|
9
11
|
|
|
10
12
|
@typing.overload
|
|
@@ -23,19 +25,40 @@ class Solution:
|
|
|
23
25
|
raise ValueError
|
|
24
26
|
|
|
25
27
|
def __solution_init_1(self, consistent: bool) -> None:
|
|
28
|
+
# Numerical value of the solution
|
|
26
29
|
self.sol: typing.Union[bool, float] = 0.0
|
|
30
|
+
# Consistency of the fuzzy KB
|
|
27
31
|
self.consistent: bool = consistent
|
|
32
|
+
# Value of the showed variables
|
|
33
|
+
self.showed_variables: dict[str, float] = dict()
|
|
28
34
|
|
|
29
35
|
def __solution_init_2(self, sol: float) -> None:
|
|
36
|
+
# Numerical value of the solution
|
|
30
37
|
self.sol: typing.Union[bool, float] = sol
|
|
38
|
+
# Consistency of the fuzzy KB
|
|
31
39
|
self.consistent: bool = True
|
|
40
|
+
# Value of the showed variables
|
|
41
|
+
self.showed_variables: dict[str, float] = dict()
|
|
32
42
|
|
|
33
43
|
def is_consistent_kb(self) -> bool:
|
|
44
|
+
"""Indicates whether the original KB is consistent or not."""
|
|
34
45
|
return self.consistent
|
|
35
46
|
|
|
36
47
|
def get_solution(self) -> typing.Union[bool, float]:
|
|
48
|
+
"""Gets the solution to some query over a consistent KB."""
|
|
37
49
|
return self.sol
|
|
38
50
|
|
|
51
|
+
def get_showed_variables(self) -> dict[str, float]:
|
|
52
|
+
"""Gets the values of some variables after solving a query over a consistent KB."""
|
|
53
|
+
return self.showed_variables
|
|
54
|
+
|
|
55
|
+
def add_showed_variable(self, var_name: str, value: float) -> None:
|
|
56
|
+
"""Sets the value of a showed variable."""
|
|
57
|
+
self.showed_variables[var_name] = value
|
|
58
|
+
|
|
59
|
+
def __hash__(self) -> int:
|
|
60
|
+
return hash(str(self))
|
|
61
|
+
|
|
39
62
|
def __repr__(self) -> str:
|
|
40
63
|
return str(self)
|
|
41
64
|
|
|
@@ -4,14 +4,21 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import VariableType
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class Variable:
|
|
7
|
+
# Name of new variables
|
|
7
8
|
VARIABLE_NAME: str = "y"
|
|
9
|
+
# Number of new variables
|
|
8
10
|
VARIABLE_NUMBER: int = 0
|
|
9
11
|
|
|
10
12
|
def __init__(self, name: str, v_type: VariableType) -> None:
|
|
13
|
+
# Lower bound of the variable
|
|
11
14
|
self.lower_bound: float = 0.0
|
|
15
|
+
# Upper bound of the variable
|
|
12
16
|
self.upper_bound: float = 0.0
|
|
17
|
+
# Name of the variable
|
|
13
18
|
self.name: str = name
|
|
19
|
+
# Type of the variable
|
|
14
20
|
self.type: VariableType = None
|
|
21
|
+
# Variable is filler value of datatype restriction
|
|
15
22
|
self.datatype_filler: bool = False
|
|
16
23
|
self.set_type(v_type)
|
|
17
24
|
|
|
@@ -7,6 +7,9 @@ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class Modifier(ABC):
|
|
10
|
+
"""
|
|
11
|
+
Fuzzy modifier.
|
|
12
|
+
"""
|
|
10
13
|
|
|
11
14
|
def __init__(self, name: str) -> None:
|
|
12
15
|
self.name: str = name
|
|
@@ -24,10 +27,28 @@ class Modifier(ABC):
|
|
|
24
27
|
|
|
25
28
|
@abstractmethod
|
|
26
29
|
def modify(self, concept: Concept) -> Concept:
|
|
30
|
+
"""
|
|
31
|
+
Modifies a fuzzy concept.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
concept (Concept): A fuzzy concept
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Concept: Fuzzy concept resulting from the application of the modifier to c.
|
|
38
|
+
"""
|
|
27
39
|
pass
|
|
28
40
|
|
|
29
41
|
@abstractmethod
|
|
30
42
|
def get_membership_degree(self, value: float) -> float:
|
|
43
|
+
"""
|
|
44
|
+
Gets the image in [0,1] of a real number to the modifier.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
value (float): A real number in the range of values of the modifier function.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
float: Image in [0,1] of x to the explicit modifier function.
|
|
51
|
+
"""
|
|
31
52
|
pass
|
|
32
53
|
|
|
33
54
|
def __repr__(self) -> str:
|
|
@@ -48,6 +48,7 @@ from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
|
|
|
48
48
|
from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
|
|
49
49
|
from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import QsugenoIntegral
|
|
50
50
|
from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
|
|
51
|
+
from fuzzy_dl_owl2.fuzzydl.concept.sigma_concept import SigmaConcept
|
|
51
52
|
from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
|
|
52
53
|
from fuzzy_dl_owl2.fuzzydl.concept.threshold_concept import ThresholdConcept
|
|
53
54
|
from fuzzy_dl_owl2.fuzzydl.concept.truth_concept import TruthConcept
|
|
@@ -564,6 +565,32 @@ class DLParser(object):
|
|
|
564
565
|
return pp.ParseResults([QsugenoIntegral(weights, concepts)])
|
|
565
566
|
return tokens
|
|
566
567
|
|
|
568
|
+
@staticmethod
|
|
569
|
+
# @pp.trace_parse_action
|
|
570
|
+
def _parse_sigma_count_concept(tokens: pp.ParseResults) -> pp.ParseResults:
|
|
571
|
+
if ConfigReader.DEBUG_PRINT:
|
|
572
|
+
Util.debug(f"\t\t_parse_sigma_count_concept -> {tokens}")
|
|
573
|
+
list_tokens: list[str] = tokens.as_list()
|
|
574
|
+
role: str = list_tokens[0]
|
|
575
|
+
concept: Concept = DLParser._to_concept(list_tokens[1])
|
|
576
|
+
individuals: list[Individual] = [
|
|
577
|
+
DLParser.kb.get_individual(token) for token in list_tokens[2:-1]
|
|
578
|
+
]
|
|
579
|
+
concept_name: str = list_tokens[-1]
|
|
580
|
+
if concept_name not in DLParser.kb.concrete_concepts:
|
|
581
|
+
Util.error(f"Error: Fuzzy cocnept {concept_name} has not been defined")
|
|
582
|
+
fuzzy_concept: Concept = DLParser.kb.get_concept(concept_name)
|
|
583
|
+
if not isinstance(
|
|
584
|
+
fuzzy_concept,
|
|
585
|
+
(RightConcreteConcept, LeftConcreteConcept, TriangularConcreteConcept),
|
|
586
|
+
):
|
|
587
|
+
Util.error(
|
|
588
|
+
f"Error: Fuzzy concept {fuzzy_concept} has to be a left, right or a triangular function."
|
|
589
|
+
)
|
|
590
|
+
return pp.ParseResults(
|
|
591
|
+
[SigmaConcept(concept, role, individuals, fuzzy_concept)]
|
|
592
|
+
)
|
|
593
|
+
|
|
567
594
|
@staticmethod
|
|
568
595
|
# @pp.trace_parse_action
|
|
569
596
|
def _parse_modifier(tokens: pp.ParseResults) -> pp.ParseResults:
|
|
@@ -973,7 +1000,6 @@ class DLParser(object):
|
|
|
973
1000
|
@staticmethod
|
|
974
1001
|
# @pp.trace_parse_action
|
|
975
1002
|
def _parse_constraints(tokens: pp.ParseResults) -> pp.ParseResults:
|
|
976
|
-
|
|
977
1003
|
if ConfigReader.DEBUG_PRINT:
|
|
978
1004
|
Util.debug(f"\t\t_parse_constraints -> {tokens}")
|
|
979
1005
|
list_tokens: list = tokens.as_list()
|
|
@@ -1456,6 +1482,8 @@ class DLParser(object):
|
|
|
1456
1482
|
|
|
1457
1483
|
lbrace = pp.Literal("(").set_results_name("lbrace").suppress()
|
|
1458
1484
|
rbrace = pp.Literal(")").set_results_name("rbrace").suppress()
|
|
1485
|
+
lbbrace = pp.Literal("{").set_results_name("lbbrace").suppress()
|
|
1486
|
+
rbbrace = pp.Literal("}").set_results_name("rbbrace").suppress()
|
|
1459
1487
|
comment = pp.one_of(["#", "%"]).set_results_name("comment").suppress()
|
|
1460
1488
|
any_not_newline = (
|
|
1461
1489
|
pp.Regex("[^\n]+").set_results_name("any_not_newline").suppress()
|
|
@@ -1737,6 +1765,17 @@ class DLParser(object):
|
|
|
1737
1765
|
)
|
|
1738
1766
|
.set_results_name("owa_integrals", list_all_matches=True)
|
|
1739
1767
|
.set_parse_action(DLParser._parse_owa_integral_concept)
|
|
1768
|
+
| (
|
|
1769
|
+
FuzzyDLKeyword.SIGMA_COUNT.get_value().suppress()
|
|
1770
|
+
+ variables # role
|
|
1771
|
+
+ concept
|
|
1772
|
+
+ lbbrace
|
|
1773
|
+
+ variables[1, ...] # list of individuals
|
|
1774
|
+
+ rbbrace
|
|
1775
|
+
+ variables # fuzzy concept name
|
|
1776
|
+
)
|
|
1777
|
+
.set_results_name("sigma_count", list_all_matches=True)
|
|
1778
|
+
.set_parse_action(DLParser._parse_sigma_count_concept)
|
|
1740
1779
|
)
|
|
1741
1780
|
+ rbrace
|
|
1742
1781
|
)
|
|
@@ -1897,13 +1936,15 @@ class DLParser(object):
|
|
|
1897
1936
|
(
|
|
1898
1937
|
lbrace
|
|
1899
1938
|
+ FuzzyDLKeyword.CONSTRAINTS.get_value()
|
|
1900
|
-
+ lbrace
|
|
1901
1939
|
+ (
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1940
|
+
lbrace
|
|
1941
|
+
+ (
|
|
1942
|
+
inequation
|
|
1943
|
+
| FuzzyDLKeyword.BINARY.get_value() + variables
|
|
1944
|
+
| FuzzyDLKeyword.FREE.get_value() + variables
|
|
1945
|
+
)
|
|
1946
|
+
+ rbrace
|
|
1947
|
+
)[1, ...]
|
|
1907
1948
|
+ rbrace
|
|
1908
1949
|
)
|
|
1909
1950
|
.set_results_name("constraints", list_all_matches=True)
|
|
@@ -7,6 +7,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import LogicOperatorType
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class PrimitiveConceptDefinition:
|
|
10
|
+
"""
|
|
11
|
+
General concept inclusion axiom.
|
|
12
|
+
"""
|
|
10
13
|
|
|
11
14
|
def __init__(
|
|
12
15
|
self,
|
|
@@ -15,9 +18,13 @@ class PrimitiveConceptDefinition:
|
|
|
15
18
|
implication: LogicOperatorType,
|
|
16
19
|
degree: float,
|
|
17
20
|
) -> None:
|
|
21
|
+
# Subsumer concept
|
|
18
22
|
self.defined: str = defined
|
|
23
|
+
# Subsumed concept
|
|
19
24
|
self.definition: Concept = definition
|
|
25
|
+
# Lower bound degree
|
|
20
26
|
self.degree: float = degree
|
|
27
|
+
# Axiom type (depends on the fuzzy implication)
|
|
21
28
|
self.implication: LogicOperatorType = implication
|
|
22
29
|
|
|
23
30
|
def clone(self) -> typing.Self:
|
|
@@ -6,6 +6,7 @@ from .related_query import RelatedQuery
|
|
|
6
6
|
from .satisfiable_query import SatisfiableQuery
|
|
7
7
|
from .subsumption_query import SubsumptionQuery
|
|
8
8
|
from .all_instances_query import AllInstancesQuery
|
|
9
|
+
from .classification_query import ClassificationQuery
|
|
9
10
|
|
|
10
11
|
from .max import *
|
|
11
12
|
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
4
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_expression import DegreeExpression
|
|
5
|
+
from fuzzy_dl_owl2.fuzzydl.exception.inconsistent_ontology_exception import (
|
|
6
|
+
InconsistentOntologyException,
|
|
7
|
+
)
|
|
4
8
|
from fuzzy_dl_owl2.fuzzydl.individual.created_individual import CreatedIndividual
|
|
5
9
|
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
6
10
|
from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
|
|
11
|
+
from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
|
|
12
|
+
from fuzzy_dl_owl2.fuzzydl.milp.milp_helper import MILPHelper
|
|
7
13
|
from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
|
|
14
|
+
from fuzzy_dl_owl2.fuzzydl.milp.term import Term
|
|
15
|
+
from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
|
|
8
16
|
from fuzzy_dl_owl2.fuzzydl.query.min.min_instance_query import MinInstanceQuery
|
|
9
17
|
from fuzzy_dl_owl2.fuzzydl.query.query import Query
|
|
18
|
+
from fuzzy_dl_owl2.fuzzydl.util.constants import VariableType
|
|
10
19
|
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
11
20
|
|
|
12
21
|
|
|
13
22
|
class AllInstancesQuery(Query):
|
|
23
|
+
"""
|
|
24
|
+
Min instance query for every individual of a knowledge base.
|
|
25
|
+
"""
|
|
26
|
+
|
|
14
27
|
def __init__(self, concept: Concept) -> None:
|
|
28
|
+
super().__init__()
|
|
15
29
|
if concept.is_concrete():
|
|
16
30
|
Util.error(f"Error: {concept} cannot be a concrete concept.")
|
|
17
31
|
self.conc = concept
|
|
@@ -27,6 +41,11 @@ class AllInstancesQuery(Query):
|
|
|
27
41
|
self.name: str = ""
|
|
28
42
|
self.individuals: list[Individual] = list(kb.individuals.values())
|
|
29
43
|
|
|
44
|
+
try:
|
|
45
|
+
kb.solve_abox()
|
|
46
|
+
except InconsistentOntologyException as e:
|
|
47
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
48
|
+
|
|
30
49
|
for i in self.individuals:
|
|
31
50
|
if isinstance(i, CreatedIndividual):
|
|
32
51
|
continue
|
|
@@ -34,12 +53,72 @@ class AllInstancesQuery(Query):
|
|
|
34
53
|
sol: Solution = q.solve(kb)
|
|
35
54
|
if sol.is_consistent_kb():
|
|
36
55
|
self.degrees.append(float(sol.get_solution()))
|
|
37
|
-
self.name += f"{q}{sol.get_solution()}"
|
|
56
|
+
self.name += f"{q}{sol.get_solution()}\n"
|
|
38
57
|
continue
|
|
39
58
|
self.name = f"Instances of {self.conc}? Inconsistent KB"
|
|
40
59
|
break
|
|
41
60
|
return sol
|
|
42
61
|
|
|
62
|
+
def solve_new(self, kb: KnowledgeBase) -> Solution:
|
|
63
|
+
"""
|
|
64
|
+
Specific algorithm to solve the instance retrieval.
|
|
65
|
+
"""
|
|
66
|
+
self.name: str = ""
|
|
67
|
+
new_variables: list[Variable] = list()
|
|
68
|
+
var_names: dict[str, str] = dict()
|
|
69
|
+
self.individuals: list[Individual] = list(kb.individuals.values())
|
|
70
|
+
cloned: KnowledgeBase = kb.clone()
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
cloned.solve_abox()
|
|
74
|
+
except InconsistentOntologyException as e:
|
|
75
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
76
|
+
|
|
77
|
+
for i in self.individuals:
|
|
78
|
+
if isinstance(i, CreatedIndividual):
|
|
79
|
+
continue
|
|
80
|
+
q: Variable = cloned.milp.get_new_variable(VariableType.SEMI_CONTINUOUS)
|
|
81
|
+
cloned.old_01_variables += 1
|
|
82
|
+
s: str = f"Is {i} instance of {self.conc}? >= "
|
|
83
|
+
var_names[str(q)] = s
|
|
84
|
+
cloned.milp.show_vars.add_variable(q, s)
|
|
85
|
+
new_variables.append(q)
|
|
86
|
+
# a: not c >= 1-q
|
|
87
|
+
cloned.add_assertion(
|
|
88
|
+
i,
|
|
89
|
+
-self.conc,
|
|
90
|
+
DegreeExpression.get_degree(Expression(1.0, Term(-1.0, q))),
|
|
91
|
+
)
|
|
92
|
+
cloned.solve_assertions()
|
|
93
|
+
obj_expr: Expression = Expression()
|
|
94
|
+
for var in new_variables:
|
|
95
|
+
obj_expr.add_term(Term(1.0, var))
|
|
96
|
+
|
|
97
|
+
MILPHelper.PRINT_LABELS = False
|
|
98
|
+
MILPHelper.PRINT_VARIABLES = False
|
|
99
|
+
MILPHelper.PARTITION = True
|
|
100
|
+
sol: Solution = cloned.optimize(obj_expr)
|
|
101
|
+
MILPHelper.PARTITION = False
|
|
102
|
+
MILPHelper.PRINT_LABELS = True
|
|
103
|
+
MILPHelper.PRINT_VARIABLES = True
|
|
104
|
+
|
|
105
|
+
if sol.is_consistent_kb():
|
|
106
|
+
ht: dict[str, float] = sol.get_showed_variables()
|
|
107
|
+
individuals_and_degrees: dict[str, float] = dict()
|
|
108
|
+
for s in ht:
|
|
109
|
+
var_name: str = var_names.get(s)
|
|
110
|
+
value: float = ht.get(s)
|
|
111
|
+
self.name += f"{var_name} {value}\n"
|
|
112
|
+
individuals_and_degrees[var_name, value]
|
|
113
|
+
|
|
114
|
+
for i in range(len(self.individuals)):
|
|
115
|
+
var_name: str = f"Is {self.individuals[i]} instance of {self.conc} >= "
|
|
116
|
+
value: float = individuals_and_degrees.get(var_name)
|
|
117
|
+
self.degrees.append(value)
|
|
118
|
+
else:
|
|
119
|
+
self.name = f"Instances of {self.conc}? Inconsistent KB"
|
|
120
|
+
return sol
|
|
121
|
+
|
|
43
122
|
def get_individuals(self) -> list[Individual]:
|
|
44
123
|
return self.individuals
|
|
45
124
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
|
|
3
|
+
from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
|
|
4
|
+
from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
|
|
5
|
+
from fuzzy_dl_owl2.fuzzydl.query.query import Query
|
|
6
|
+
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ClassificationQuery(Query):
|
|
10
|
+
|
|
11
|
+
def __init__(self) -> None:
|
|
12
|
+
super().__init__()
|
|
13
|
+
|
|
14
|
+
def preprocess(self, kb: KnowledgeBase) -> None:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
def solve(self, kb: KnowledgeBase) -> Solution:
|
|
18
|
+
try:
|
|
19
|
+
kb.classify()
|
|
20
|
+
return Solution(1.0)
|
|
21
|
+
except Exception as ex:
|
|
22
|
+
Util.debug(traceback.format_exc())
|
|
23
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
24
|
+
|
|
25
|
+
def __str__(self) -> str:
|
|
26
|
+
return "Classify? <= "
|
|
@@ -24,6 +24,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
24
24
|
class DefuzzifyQuery(Query):
|
|
25
25
|
|
|
26
26
|
def __init__(self, c: Concept, ind: Individual, feature_name: str) -> None:
|
|
27
|
+
super().__init__()
|
|
27
28
|
self.conc: Concept = c
|
|
28
29
|
self.a: Individual = ind
|
|
29
30
|
self.f_name: str = feature_name
|
|
@@ -69,7 +70,7 @@ class DefuzzifyQuery(Query):
|
|
|
69
70
|
Util.warning("Warning: Problem in defuzzification. Answer is 0.")
|
|
70
71
|
return None
|
|
71
72
|
except InconsistentOntologyException:
|
|
72
|
-
return Solution(
|
|
73
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
73
74
|
|
|
74
75
|
@abstractmethod
|
|
75
76
|
def get_obj_expression(self, variable: Variable) -> Expression:
|
|
@@ -9,6 +9,10 @@ from fuzzy_dl_owl2.fuzzydl.query.defuzzify.defuzzify_query import DefuzzifyQuery
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
class LomDefuzzifyQuery(DefuzzifyQuery):
|
|
12
|
+
"""
|
|
13
|
+
Largest of maxima defuzzification query
|
|
14
|
+
"""
|
|
15
|
+
|
|
12
16
|
def __init__(self, c: Concept, ind: Individual, feature_name: str) -> None:
|
|
13
17
|
super().__init__(c, ind, feature_name)
|
|
14
18
|
|
|
@@ -25,6 +25,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
class MomDefuzzifyQuery(DefuzzifyQuery):
|
|
28
|
+
"""
|
|
29
|
+
Middle of maxima defuzzification query.
|
|
30
|
+
"""
|
|
28
31
|
|
|
29
32
|
def __init__(self, c: Concept, ind: Individual, feature_name: str) -> None:
|
|
30
33
|
super().__init__(c, ind, feature_name)
|
|
@@ -51,7 +54,7 @@ class MomDefuzzifyQuery(DefuzzifyQuery):
|
|
|
51
54
|
Util.warning("Warning: Problem in defuzzification. Answer is 0.")
|
|
52
55
|
return None
|
|
53
56
|
except InconsistentOntologyException:
|
|
54
|
-
return Solution(
|
|
57
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
55
58
|
|
|
56
59
|
rel_set: list[Relation] = ind.role_relations.get(self.f_name)
|
|
57
60
|
b: CreatedIndividual = typing.cast(
|
|
@@ -86,9 +89,10 @@ class MomDefuzzifyQuery(DefuzzifyQuery):
|
|
|
86
89
|
traceback.print_exc()
|
|
87
90
|
except InconsistentOntologyException as e:
|
|
88
91
|
traceback.print_exc()
|
|
89
|
-
return Solution(
|
|
92
|
+
return Solution(Solution.INCONSISTENT_KB)
|
|
90
93
|
|
|
91
94
|
def get_obj_expression(self, variable: Variable) -> Expression:
|
|
95
|
+
# Put anything here, we do not use this method
|
|
92
96
|
return Expression(Term(-1.0, variable))
|
|
93
97
|
|
|
94
98
|
def __str__(self) -> str:
|
|
@@ -10,6 +10,8 @@ from fuzzy_dl_owl2.fuzzydl.query.defuzzify.defuzzify_query import DefuzzifyQuery
|
|
|
10
10
|
|
|
11
11
|
class SomDefuzzifyQuery(DefuzzifyQuery):
|
|
12
12
|
|
|
13
|
+
"""Smallest of maxima defuzzification query."""
|
|
14
|
+
|
|
13
15
|
def __init__(self, c: Concept, ind: Individual, f_name: str) -> None:
|
|
14
16
|
super().__init__(c, ind, f_name)
|
|
15
17
|
|