fuzzy-dl-owl2 1.0.2__py3-none-any.whl → 1.0.3__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 (25) hide show
  1. fuzzy_dl_owl2/fuzzydl/concept/approximation_concept.py +35 -10
  2. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +2 -1
  3. fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +1 -0
  4. fuzzy_dl_owl2/fuzzydl/concept/implies_concept.py +14 -11
  5. fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +10 -6
  6. fuzzy_dl_owl2/fuzzydl/concept/value_concept.py +1 -1
  7. fuzzy_dl_owl2/fuzzydl/concrete_feature.py +7 -1
  8. fuzzy_dl_owl2/fuzzydl/feature_function.py +16 -2
  9. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +1 -1
  10. fuzzy_dl_owl2/fuzzydl/knowledge_base.py +494 -358
  11. fuzzy_dl_owl2/fuzzydl/milp/expression.py +4 -2
  12. fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +3 -2
  13. fuzzy_dl_owl2/fuzzydl/milp/variable.py +3 -0
  14. fuzzy_dl_owl2/fuzzydl/modifier/triangular_modifier.py +1 -1
  15. fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +1465 -1210
  16. fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +14 -7
  17. fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +2 -2
  18. fuzzy_dl_owl2/fuzzydl/util/config_reader.py +0 -6
  19. fuzzy_dl_owl2/fuzzydl/util/constants.py +10 -9
  20. fuzzy_dl_owl2/fuzzydl/util/utils.py +48 -7
  21. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +1 -1
  22. {fuzzy_dl_owl2-1.0.2.dist-info → fuzzy_dl_owl2-1.0.3.dist-info}/METADATA +9 -7
  23. {fuzzy_dl_owl2-1.0.2.dist-info → fuzzy_dl_owl2-1.0.3.dist-info}/RECORD +25 -25
  24. {fuzzy_dl_owl2-1.0.2.dist-info → fuzzy_dl_owl2-1.0.3.dist-info}/LICENSE +0 -0
  25. {fuzzy_dl_owl2-1.0.2.dist-info → fuzzy_dl_owl2-1.0.3.dist-info}/WHEEL +0 -0
@@ -5,107 +5,107 @@ import os
5
5
  import time
6
6
  import traceback
7
7
  import typing
8
- from functools import partial, reduce
8
+ from functools import reduce
9
9
 
10
10
  import pyparsing as pp
11
11
 
12
12
  from fuzzy_dl_owl2.fuzzydl.concept.all_some_concept import AllSomeConcept
13
- from fuzzy_dl_owl2.fuzzydl.concept.approximation_concept import \
14
- ApproximationConcept
13
+ from fuzzy_dl_owl2.fuzzydl.concept.approximation_concept import ApproximationConcept
15
14
  from fuzzy_dl_owl2.fuzzydl.concept.choquet_integral import ChoquetIntegral
16
15
  from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
17
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.crisp_concrete_concept import \
18
- CrispConcreteConcept
19
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import \
20
- FuzzyConcreteConcept
21
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_number.triangular_fuzzy_number import \
22
- TriangularFuzzyNumber
23
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.left_concrete_concept import \
24
- LeftConcreteConcept
25
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.linear_concrete_concept import \
26
- LinearConcreteConcept
27
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.modified_concrete_concept import \
28
- ModifiedConcreteConcept
29
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.right_concrete_concept import \
30
- RightConcreteConcept
31
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.trapezoidal_concrete_concept import \
32
- TrapezoidalConcreteConcept
33
- from fuzzy_dl_owl2.fuzzydl.concept.concrete.triangular_concrete_concept import \
34
- TriangularConcreteConcept
35
- from fuzzy_dl_owl2.fuzzydl.concept.ext_threshold_concept import \
36
- ExtThresholdConcept
16
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.crisp_concrete_concept import (
17
+ CrispConcreteConcept,
18
+ )
19
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
20
+ FuzzyConcreteConcept,
21
+ )
22
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_number.triangular_fuzzy_number import (
23
+ TriangularFuzzyNumber,
24
+ )
25
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.left_concrete_concept import (
26
+ LeftConcreteConcept,
27
+ )
28
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.linear_concrete_concept import (
29
+ LinearConcreteConcept,
30
+ )
31
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.modified_concrete_concept import (
32
+ ModifiedConcreteConcept,
33
+ )
34
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.right_concrete_concept import (
35
+ RightConcreteConcept,
36
+ )
37
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.trapezoidal_concrete_concept import (
38
+ TrapezoidalConcreteConcept,
39
+ )
40
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.triangular_concrete_concept import (
41
+ TriangularConcreteConcept,
42
+ )
43
+ from fuzzy_dl_owl2.fuzzydl.concept.ext_threshold_concept import ExtThresholdConcept
37
44
  from fuzzy_dl_owl2.fuzzydl.concept.has_value_concept import HasValueConcept
38
45
  from fuzzy_dl_owl2.fuzzydl.concept.implies_concept import ImpliesConcept
39
46
  from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
40
47
  from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
41
48
  from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
42
- from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import \
43
- QsugenoIntegral
49
+ from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import QsugenoIntegral
44
50
  from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
45
51
  from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
46
52
  from fuzzy_dl_owl2.fuzzydl.concept.threshold_concept import ThresholdConcept
47
53
  from fuzzy_dl_owl2.fuzzydl.concept.truth_concept import TruthConcept
48
54
  from fuzzy_dl_owl2.fuzzydl.concept.weighted_concept import WeightedConcept
49
- from fuzzy_dl_owl2.fuzzydl.concept.weighted_max_concept import \
50
- WeightedMaxConcept
51
- from fuzzy_dl_owl2.fuzzydl.concept.weighted_min_concept import \
52
- WeightedMinConcept
53
- from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_concept import \
54
- WeightedSumConcept
55
- from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_zero_concept import \
56
- WeightedSumZeroConcept
55
+ from fuzzy_dl_owl2.fuzzydl.concept.weighted_max_concept import WeightedMaxConcept
56
+ from fuzzy_dl_owl2.fuzzydl.concept.weighted_min_concept import WeightedMinConcept
57
+ from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_concept import WeightedSumConcept
58
+ from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_zero_concept import (
59
+ WeightedSumZeroConcept,
60
+ )
57
61
  from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
58
62
  from fuzzy_dl_owl2.fuzzydl.degree.degree_expression import DegreeExpression
59
63
  from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
60
64
  from fuzzy_dl_owl2.fuzzydl.degree.degree_variable import DegreeVariable
61
- from fuzzy_dl_owl2.fuzzydl.exception.inconsistent_ontology_exception import \
62
- InconsistentOntologyException
65
+ from fuzzy_dl_owl2.fuzzydl.exception.inconsistent_ontology_exception import (
66
+ InconsistentOntologyException,
67
+ )
63
68
  from fuzzy_dl_owl2.fuzzydl.feature_function import FeatureFunction
64
69
  from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
65
70
  from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
66
71
  from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
72
+ from fuzzy_dl_owl2.fuzzydl.milp.inequation import Inequation
67
73
  from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
68
74
  from fuzzy_dl_owl2.fuzzydl.milp.term import Term
69
75
  from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
70
76
  from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
71
77
  from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
72
- from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import \
73
- TriangularModifier
78
+ from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import TriangularModifier
74
79
  from fuzzy_dl_owl2.fuzzydl.query.all_instances_query import AllInstancesQuery
75
80
  from fuzzy_dl_owl2.fuzzydl.query.bnp_query import BnpQuery
76
- from fuzzy_dl_owl2.fuzzydl.query.defuzzify.lom_defuzzify_query import \
77
- LomDefuzzifyQuery
78
- from fuzzy_dl_owl2.fuzzydl.query.defuzzify.mom_defuzzify_query import \
79
- MomDefuzzifyQuery
80
- from fuzzy_dl_owl2.fuzzydl.query.defuzzify.som_defuzzify_query import \
81
- SomDefuzzifyQuery
82
- from fuzzy_dl_owl2.fuzzydl.query.kb_satisfiable_query import \
83
- KbSatisfiableQuery
84
- from fuzzy_dl_owl2.fuzzydl.query.max.max_instance_query import \
85
- MaxInstanceQuery
81
+ from fuzzy_dl_owl2.fuzzydl.query.defuzzify.lom_defuzzify_query import LomDefuzzifyQuery
82
+ from fuzzy_dl_owl2.fuzzydl.query.defuzzify.mom_defuzzify_query import MomDefuzzifyQuery
83
+ from fuzzy_dl_owl2.fuzzydl.query.defuzzify.som_defuzzify_query import SomDefuzzifyQuery
84
+ from fuzzy_dl_owl2.fuzzydl.query.kb_satisfiable_query import KbSatisfiableQuery
85
+ from fuzzy_dl_owl2.fuzzydl.query.max.max_instance_query import MaxInstanceQuery
86
86
  from fuzzy_dl_owl2.fuzzydl.query.max.max_query import MaxQuery
87
87
  from fuzzy_dl_owl2.fuzzydl.query.max.max_related_query import MaxRelatedQuery
88
- from fuzzy_dl_owl2.fuzzydl.query.max.max_satisfiable_query import \
89
- MaxSatisfiableQuery
90
- from fuzzy_dl_owl2.fuzzydl.query.max.max_subsumes_query import \
91
- MaxSubsumesQuery
92
- from fuzzy_dl_owl2.fuzzydl.query.min.min_instance_query import \
93
- MinInstanceQuery
88
+ from fuzzy_dl_owl2.fuzzydl.query.max.max_satisfiable_query import MaxSatisfiableQuery
89
+ from fuzzy_dl_owl2.fuzzydl.query.max.max_subsumes_query import MaxSubsumesQuery
90
+ from fuzzy_dl_owl2.fuzzydl.query.min.min_instance_query import MinInstanceQuery
94
91
  from fuzzy_dl_owl2.fuzzydl.query.min.min_query import MinQuery
95
92
  from fuzzy_dl_owl2.fuzzydl.query.min.min_related_query import MinRelatedQuery
96
- from fuzzy_dl_owl2.fuzzydl.query.min.min_satisfiable_query import \
97
- MinSatisfiableQuery
98
- from fuzzy_dl_owl2.fuzzydl.query.min.min_subsumes_query import \
99
- MinSubsumesQuery
93
+ from fuzzy_dl_owl2.fuzzydl.query.min.min_satisfiable_query import MinSatisfiableQuery
94
+ from fuzzy_dl_owl2.fuzzydl.query.min.min_subsumes_query import MinSubsumesQuery
100
95
  from fuzzy_dl_owl2.fuzzydl.query.query import Query
101
96
  from fuzzy_dl_owl2.fuzzydl.util import constants, utils
102
97
  from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
103
- from fuzzy_dl_owl2.fuzzydl.util.constants import (ConceptType, FuzzyDLKeyword,
104
- FuzzyLogic, InequalityType,
105
- LogicOperatorType,
106
- RestrictionType,
107
- VariableType)
98
+ from fuzzy_dl_owl2.fuzzydl.util.constants import (
99
+ ConceptType,
100
+ FuzzyDLKeyword,
101
+ FuzzyLogic,
102
+ InequalityType,
103
+ LogicOperatorType,
104
+ RestrictionType,
105
+ VariableType,
106
+ )
108
107
  from fuzzy_dl_owl2.fuzzydl.util.util import Util
108
+ from fuzzy_dl_owl2.fuzzydl.util.utils import class_debugging
109
109
 
110
110
  TODAY: datetime.datetime = datetime.datetime.today()
111
111
  LOG_DIR: str = os.path.join(
@@ -119,1116 +119,1328 @@ if not os.path.exists(LOG_DIR):
119
119
  os.makedirs(LOG_DIR)
120
120
 
121
121
 
122
- def _check_abstract(c: Concept) -> None:
123
- if c.is_concrete():
124
- Util.error(f"Error: Concept {c} should be abstract.")
125
-
126
-
127
- def _to_number(tokens: pp.ParseResults) -> float | int:
128
- v: float = float(str(tokens.as_list()[0]))
129
- return int(v) if v.is_integer() else v
130
-
131
-
132
- # @pp.trace_parse_action
133
- def _fuzzy_logic_parser(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
134
- if ConfigReader.DEBUG_PRINT:
135
- Util.debug(f"\t\t_fuzzy_logic_parser -> {tokens}")
136
- kb.set_logic(FuzzyLogic(str(tokens.as_list()[0]).lower()))
137
- return tokens
138
-
139
-
140
- def _to_concept(kb: KnowledgeBase, c: typing.Union[str, Concept]) -> Concept:
141
- if ConfigReader.DEBUG_PRINT:
142
- Util.debug(f"\t\t_to_concept -> {c}")
143
- return c if isinstance(c, Concept) else kb.get_concept(c)
144
- # return kb.get_concept(str(c))
145
-
146
-
147
- def _to_top_bottom_concept(
148
- kb: KnowledgeBase, tokens: pp.ParseResults
149
- ) -> pp.ParseResults:
150
- if ConfigReader.DEBUG_PRINT:
151
- Util.debug(f"\t\t_to_top_bottom_concept -> {tokens}")
152
- list_tokens: list = tokens.as_list()
153
- if list_tokens[0] == FuzzyDLKeyword.TOP:
154
- return pp.ParseResults([TruthConcept.get_top()])
155
- elif list_tokens[0] == FuzzyDLKeyword.BOTTOM:
156
- return pp.ParseResults([TruthConcept.get_bottom()])
157
- else:
158
- return pp.ParseResults([_to_concept(kb, list_tokens[0])])
159
-
160
-
161
- def _get_modifier(kb: KnowledgeBase, m: str) -> Modifier:
162
- if ConfigReader.DEBUG_PRINT:
163
- Util.debug(f"\t\t_get_modifier -> {m}")
164
- if len(kb.modifiers) == 0 or m not in kb.modifiers:
165
- Util.error(f"Error: {m} modifier is not defined.")
166
- return kb.modifiers.get(m)
167
-
168
-
169
- def _parse_binary_concept(
170
- kb: KnowledgeBase, tokens: pp.ParseResults
171
- ) -> pp.ParseResults:
172
- if ConfigReader.DEBUG_PRINT:
173
- Util.debug(f"\t\t_parse_binary_concept -> {tokens}")
174
- list_tokens: list = tokens.as_list()
175
- operator: str = list_tokens[0]
176
- if operator == FuzzyDLKeyword.AND:
177
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
178
- for c in list_tokens:
179
- _check_abstract(c)
180
- if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
122
+ @class_debugging()
123
+ class DLParser(object):
124
+
125
+ kb: KnowledgeBase = None
126
+ queries_list: list[Query] = []
127
+
128
+ @staticmethod
129
+ def _check_abstract(c: Concept) -> None:
130
+ if c.is_concrete():
131
+ Util.error(f"Error: Concept {c} should be abstract.")
132
+
133
+ @staticmethod
134
+ # @pp.trace_parse_action
135
+ def _to_number(tokens: pp.ParseResults) -> float | int:
136
+ v: float = float(str(tokens.as_list()[0]))
137
+ return int(v) if v.is_integer() else v
138
+
139
+ @staticmethod
140
+ # @pp.trace_parse_action
141
+ def _fuzzy_logic_parser(tokens: pp.ParseResults) -> pp.ParseResults:
142
+ if ConfigReader.DEBUG_PRINT:
143
+ Util.debug(f"\t\t_fuzzy_logic_parser -> {tokens}")
144
+ DLParser.kb.set_logic(FuzzyLogic(str(tokens.as_list()[0]).lower()))
145
+ return tokens
146
+
147
+ @staticmethod
148
+ # @pp.trace_parse_action
149
+ def _to_concept(c: typing.Union[str, Concept]) -> Concept:
150
+
151
+ if ConfigReader.DEBUG_PRINT:
152
+ Util.debug(f"\t\t_to_concept -> {c}")
153
+ return c if isinstance(c, Concept) else DLParser.kb.get_concept(c)
154
+ # return DLParser.kb.get_concept(str(c))
155
+
156
+ @staticmethod
157
+ # @pp.trace_parse_action
158
+ def _to_top_bottom_concept(tokens: pp.ParseResults) -> pp.ParseResults:
159
+ if ConfigReader.DEBUG_PRINT:
160
+ Util.debug(f"\t\t_to_top_bottom_concept -> {tokens}")
161
+ list_tokens: list = tokens.as_list()
162
+ if list_tokens[0] == FuzzyDLKeyword.TOP:
163
+ return pp.ParseResults([TruthConcept.get_top()])
164
+ elif list_tokens[0] == FuzzyDLKeyword.BOTTOM:
165
+ return pp.ParseResults([TruthConcept.get_bottom()])
166
+ else:
167
+ return pp.ParseResults([DLParser._to_concept(list_tokens[0])])
168
+
169
+ @staticmethod
170
+ # @pp.trace_parse_action
171
+ def _get_modifier(m: str) -> Modifier:
172
+ if ConfigReader.DEBUG_PRINT:
173
+ Util.debug(f"\t\t_get_modifier -> {m}")
174
+ if len(DLParser.kb.modifiers) == 0 or m not in DLParser.kb.modifiers:
175
+ Util.error(f"Error: {m} modifier is not defined.")
176
+ return DLParser.kb.modifiers.get(m)
177
+
178
+ @staticmethod
179
+ # @pp.trace_parse_action
180
+ def _parse_binary_concept(tokens: pp.ParseResults) -> pp.ParseResults:
181
+
182
+ if ConfigReader.DEBUG_PRINT:
183
+ Util.debug(f"\t\t_parse_binary_concept -> {tokens}")
184
+ list_tokens: list = tokens.as_list()
185
+ operator: str = list_tokens[0]
186
+ if isinstance(operator, Concept):
187
+ return tokens
188
+ if operator == FuzzyDLKeyword.AND:
189
+ list_tokens: list[Concept] = [
190
+ DLParser._to_concept(t) for t in list_tokens[1:]
191
+ ]
192
+ for c in list_tokens:
193
+ DLParser._check_abstract(c)
194
+ if DLParser.kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
195
+ return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
196
+ elif DLParser.kb.get_logic() == FuzzyLogic.ZADEH:
197
+ return pp.ParseResults([OperatorConcept.goedel_and(*list_tokens)])
198
+ return pp.ParseResults([OperatorConcept.and_(*list_tokens)])
199
+ elif operator == FuzzyDLKeyword.LUKASIEWICZ_AND:
200
+ list_tokens: list[Concept] = [
201
+ DLParser._to_concept(t) for t in list_tokens[1:]
202
+ ]
203
+ if DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL:
204
+ Util.error(
205
+ "Error: LUKASIEWICZ_AND cannot be used under classical reasoner."
206
+ )
207
+ for c in list_tokens:
208
+ DLParser._check_abstract(c)
181
209
  return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
182
- elif kb.get_logic() == FuzzyLogic.ZADEH:
210
+ elif operator == FuzzyDLKeyword.GOEDEL_AND:
211
+ list_tokens: list[Concept] = [
212
+ DLParser._to_concept(t) for t in list_tokens[1:]
213
+ ]
214
+ if DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL:
215
+ Util.error("Error: GOEDEL_AND cannot be used under classical reasoner.")
216
+ for c in list_tokens:
217
+ DLParser._check_abstract(c)
183
218
  return pp.ParseResults([OperatorConcept.goedel_and(*list_tokens)])
184
- return pp.ParseResults([OperatorConcept.and_(*list_tokens)])
185
- elif operator == FuzzyDLKeyword.LUKASIEWICZ_AND:
186
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
187
- if kb.get_logic() == FuzzyLogic.CLASSICAL:
188
- Util.error(
189
- "Error: LUKASIEWICZ_AND cannot be used under classical reasoner."
190
- )
191
- for c in list_tokens:
192
- _check_abstract(c)
193
- return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
194
- elif operator == FuzzyDLKeyword.GOEDEL_AND:
195
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
196
- if kb.get_logic() == FuzzyLogic.CLASSICAL:
197
- Util.error("Error: GOEDEL_AND cannot be used under classical reasoner.")
198
- for c in list_tokens:
199
- _check_abstract(c)
200
- return pp.ParseResults([OperatorConcept.goedel_and(*list_tokens)])
201
- elif operator == FuzzyDLKeyword.OR:
202
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
203
- for c in list_tokens:
204
- _check_abstract(c)
205
- if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
219
+ elif operator == FuzzyDLKeyword.OR:
220
+ list_tokens: list[Concept] = [
221
+ DLParser._to_concept(t) for t in list_tokens[1:]
222
+ ]
223
+ for c in list_tokens:
224
+ DLParser._check_abstract(c)
225
+ if DLParser.kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
226
+ return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
227
+ elif DLParser.kb.get_logic() == FuzzyLogic.ZADEH:
228
+ return pp.ParseResults([OperatorConcept.goedel_or(*list_tokens)])
229
+ return pp.ParseResults([OperatorConcept.or_(*list_tokens)])
230
+ elif operator == FuzzyDLKeyword.LUKASIEWICZ_OR:
231
+ list_tokens: list[Concept] = [
232
+ DLParser._to_concept(t) for t in list_tokens[1:]
233
+ ]
234
+ if DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL:
235
+ Util.error(
236
+ "Error: LUKASIEWICZ_OR cannot be used under classical reasoner."
237
+ )
238
+ for c in list_tokens:
239
+ DLParser._check_abstract(c)
206
240
  return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
207
- elif kb.get_logic() == FuzzyLogic.ZADEH:
241
+ elif operator == FuzzyDLKeyword.GOEDEL_OR:
242
+ list_tokens: list[Concept] = [
243
+ DLParser._to_concept(t) for t in list_tokens[1:]
244
+ ]
245
+ if DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL:
246
+ Util.error("Error: GOEDEL_OR cannot be used under classical reasoner.")
247
+ for c in list_tokens:
248
+ DLParser._check_abstract(c)
208
249
  return pp.ParseResults([OperatorConcept.goedel_or(*list_tokens)])
209
- return pp.ParseResults([OperatorConcept.or_(*list_tokens)])
210
- elif operator == FuzzyDLKeyword.LUKASIEWICZ_OR:
211
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
212
- if kb.get_logic() == FuzzyLogic.CLASSICAL:
213
- Util.error("Error: LUKASIEWICZ_OR cannot be used under classical reasoner.")
214
- for c in list_tokens:
215
- _check_abstract(c)
216
- return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
217
- elif operator == FuzzyDLKeyword.GOEDEL_OR:
218
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
219
- if kb.get_logic() == FuzzyLogic.CLASSICAL:
220
- Util.error("Error: GOEDEL_OR cannot be used under classical reasoner.")
221
- for c in list_tokens:
222
- _check_abstract(c)
223
- return pp.ParseResults([OperatorConcept.goedel_or(*list_tokens)])
224
- elif operator in (
225
- FuzzyDLKeyword.IMPLIES,
226
- FuzzyDLKeyword.GOEDEL_IMPLIES,
227
- FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
228
- FuzzyDLKeyword.ZADEH_IMPLIES,
229
- FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
230
- ):
231
- list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
232
- for c in list_tokens:
233
- _check_abstract(c)
234
- if kb.get_logic() == FuzzyLogic.ZADEH:
250
+ elif operator in (
251
+ FuzzyDLKeyword.IMPLIES,
252
+ FuzzyDLKeyword.GOEDEL_IMPLIES,
253
+ FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
254
+ FuzzyDLKeyword.ZADEH_IMPLIES,
255
+ FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
256
+ ):
257
+ list_tokens: list[Concept] = [
258
+ DLParser._to_concept(t) for t in list_tokens[1:]
259
+ ]
260
+ for c in list_tokens:
261
+ DLParser._check_abstract(c)
262
+ # degree: Degree = list_tokens[2] if len(list_tokens) == 3 else DegreeNumeric.get_one()
263
+ # if operator == FuzzyDLKeyword.IMPLIES:
264
+ # return pp.ParseResults([DLParser.kb.implies(list_tokens[0], list_tokens[1], degree)])
265
+ # elif operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
266
+ # return pp.ParseResults([DLParser.kb.goedel_implies(list_tokens[0], list_tokens[1], degree)])
267
+ # elif operator == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
268
+ # return pp.ParseResults([DLParser.kb.lukasiewicz_implies(list_tokens[0], list_tokens[1], degree)])
269
+ # elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
270
+ # return pp.ParseResults([DLParser.kb.zadeh_implies(list_tokens[0], list_tokens[1])])
271
+ # elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
272
+ # return pp.ParseResults([DLParser.kb.kleene_dienes_implies(list_tokens[0], list_tokens[1], degree)])
273
+ if DLParser.kb.get_logic() == FuzzyLogic.ZADEH:
274
+ return pp.ParseResults(
275
+ [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
276
+ )
277
+ elif DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL:
278
+ if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
279
+ Util.error(
280
+ "Error: GOEDEL_IMPLIES cannot be used under classical reasoner."
281
+ )
282
+ elif operator == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
283
+ Util.error(
284
+ "Error: LUKASIEWICZ_IMPLIES cannot be used under classical reasoner."
285
+ )
286
+ elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
287
+ Util.error(
288
+ "Error: ZADEH_IMPLIES cannot be used under classical reasoner."
289
+ )
290
+ elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
291
+ Util.error(
292
+ "Error: KLEENE_DIENES_IMPLIES cannot be used under classical reasoner."
293
+ )
294
+ if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
295
+ return pp.ParseResults(
296
+ [ImpliesConcept.goedel_implies(list_tokens[0], list_tokens[1])]
297
+ )
298
+ elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
299
+ return pp.ParseResults(
300
+ [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
301
+ )
302
+ elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
303
+ return pp.ParseResults(
304
+ [
305
+ ImpliesConcept.kleene_dienes_implies(
306
+ list_tokens[0], list_tokens[1]
307
+ )
308
+ ]
309
+ )
235
310
  return pp.ParseResults(
236
- [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
311
+ [ImpliesConcept.lukasiewicz_implies(list_tokens[0], list_tokens[1])]
237
312
  )
238
- elif kb.get_logic() == FuzzyLogic.CLASSICAL:
239
- if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
240
- Util.error(
241
- "Error: GOEDEL_IMPLIES cannot be used under classical reasoner."
313
+ elif operator == FuzzyDLKeyword.ALL:
314
+ role: str = list_tokens[1]
315
+ concept: Concept = DLParser._to_concept(list_tokens[2])
316
+ DLParser.kb.check_role(role, concept)
317
+ return pp.ParseResults([AllSomeConcept.all(role, concept)])
318
+ elif operator == FuzzyDLKeyword.SOME:
319
+ c: Concept = DLParser._to_concept(list_tokens[2])
320
+ role: str = list_tokens[1]
321
+ DLParser.kb.check_role(role, c)
322
+ return pp.ParseResults([AllSomeConcept.some(role, c)])
323
+ elif operator == FuzzyDLKeyword.HAS_VALUE:
324
+ ind: Individual = DLParser.kb.get_individual(list_tokens[2])
325
+ DLParser.kb.check_role(role, TruthConcept.get_top())
326
+ return pp.ParseResults([HasValueConcept.has_value(role, ind)])
327
+ elif operator in (
328
+ FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION,
329
+ FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION,
330
+ FuzzyDLKeyword.UPPER_APPROXIMATION,
331
+ FuzzyDLKeyword.LOWER_APPROXIMATION,
332
+ FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION,
333
+ FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION,
334
+ ):
335
+ role: str = list_tokens[1]
336
+ concept: Concept = DLParser._to_concept(list_tokens[2])
337
+ if role not in DLParser.kb.similarity_relations:
338
+ Util.error(f"Error: Similarity relation {role} has not been defined.")
339
+
340
+ if operator == FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION:
341
+ return pp.ParseResults(
342
+ [
343
+ ApproximationConcept.tight_upper_approx(
344
+ role, concept
345
+ ).to_all_some_concept()
346
+ ]
242
347
  )
243
- elif operator == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
244
- Util.error(
245
- "Error: LUKASIEWICZ_IMPLIES cannot be used under classical reasoner."
348
+ elif operator == FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION:
349
+ return pp.ParseResults(
350
+ [
351
+ ApproximationConcept.tight_lower_approx(
352
+ role, concept
353
+ ).to_all_some_concept()
354
+ ]
246
355
  )
247
- elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
356
+ elif operator == FuzzyDLKeyword.UPPER_APPROXIMATION:
357
+ return pp.ParseResults(
358
+ [
359
+ ApproximationConcept.upper_approx(
360
+ role, concept
361
+ ).to_all_some_concept()
362
+ ]
363
+ )
364
+ elif operator == FuzzyDLKeyword.LOWER_APPROXIMATION:
365
+ return pp.ParseResults(
366
+ [
367
+ ApproximationConcept.lower_approx(
368
+ role, concept
369
+ ).to_all_some_concept()
370
+ ]
371
+ )
372
+ elif operator == FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION:
373
+ return pp.ParseResults(
374
+ [
375
+ ApproximationConcept.loose_upper_approx(
376
+ role, concept
377
+ ).to_all_some_concept()
378
+ ]
379
+ )
380
+ elif operator == FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION:
381
+ return pp.ParseResults(
382
+ [
383
+ ApproximationConcept.loose_lower_approx(
384
+ role, concept
385
+ ).to_all_some_concept()
386
+ ]
387
+ )
388
+ return tokens
389
+
390
+ @staticmethod
391
+ # @pp.trace_parse_action
392
+ def _parse_unary_concept(tokens: pp.ParseResults) -> pp.ParseResults:
393
+
394
+ if ConfigReader.DEBUG_PRINT:
395
+ Util.debug(f"\t\t_parse_unary_concept -> {tokens}")
396
+ list_tokens: list[str] = tokens.as_list()
397
+ operator: str = list_tokens[0]
398
+ if operator == FuzzyDLKeyword.NOT:
399
+ concept: Concept = DLParser._to_concept(list_tokens[1])
400
+ return pp.ParseResults([-concept])
401
+ elif operator == FuzzyDLKeyword.SELF:
402
+ role: str = list_tokens[1]
403
+ if role in DLParser.kb.concrete_roles:
404
+ Util.error(f"Error: Role {role} cannot be concrete and abstract.")
405
+ DLParser.kb.abstract_roles.add(role)
406
+ return pp.ParseResults([SelfConcept.self(role)])
407
+ return tokens
408
+
409
+ @staticmethod
410
+ # @pp.trace_parse_action
411
+ def _parse_modifier_concept(tokens: pp.ParseResults) -> pp.ParseResults:
412
+
413
+ if ConfigReader.DEBUG_PRINT:
414
+ Util.debug(f"\t\t_parse_modifier_concept -> {tokens}")
415
+ list_tokens: list[str] = tokens.as_list()
416
+ mod: Modifier = DLParser._get_modifier(list_tokens[0])
417
+ concept: Concept = DLParser._to_concept(list_tokens[1])
418
+ return pp.ParseResults([mod.modify(concept)])
419
+
420
+ @staticmethod
421
+ # @pp.trace_parse_action
422
+ def _parse_threshold_concept(tokens: pp.ParseResults):
423
+
424
+ if ConfigReader.DEBUG_PRINT:
425
+ Util.debug(f"\t\t_parse_threshold_concept -> {tokens}")
426
+ list_tokens: list[str] = tokens.as_list()
427
+ operator: str = list_tokens[0]
428
+ concept: Concept = DLParser._to_concept(list_tokens[2])
429
+ DLParser._check_abstract(concept)
430
+ if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
431
+ if isinstance(list_tokens[1], (int, float)):
432
+ return pp.ParseResults(
433
+ [ThresholdConcept.pos_threshold(list_tokens[1], concept)]
434
+ )
435
+ elif isinstance(list_tokens[1], str):
436
+ return pp.ParseResults(
437
+ [
438
+ ExtThresholdConcept.extended_pos_threshold(
439
+ DLParser.kb.milp.get_variable(list_tokens[1]), concept
440
+ )
441
+ ]
442
+ )
443
+ elif operator == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
444
+ if isinstance(list_tokens[1], (int, float)):
445
+ return pp.ParseResults(
446
+ [ThresholdConcept.neg_threshold(list_tokens[1], concept)]
447
+ )
448
+ elif isinstance(list_tokens[1], str):
449
+ return pp.ParseResults(
450
+ [
451
+ ExtThresholdConcept.extended_neg_threshold(
452
+ DLParser.kb.milp.get_variable(list_tokens[1]), concept
453
+ )
454
+ ]
455
+ )
456
+ elif operator == FuzzyDLKeyword.EQUALS:
457
+ if isinstance(list_tokens[1], (int, float)):
458
+ return pp.ParseResults([ThresholdConcept.ea(list_tokens[1], concept)])
459
+ elif isinstance(list_tokens[1], str):
460
+ return pp.ParseResults(
461
+ [
462
+ ExtThresholdConcept.extended_neg_threshold(
463
+ DLParser.kb.milp.get_variable(list_tokens[1]), concept
464
+ )
465
+ ]
466
+ )
467
+ return tokens
468
+
469
+ @staticmethod
470
+ # @pp.trace_parse_action
471
+ def _parse_weighted_concept_simple(tokens: pp.ParseResults) -> pp.ParseResults:
472
+
473
+ if ConfigReader.DEBUG_PRINT:
474
+ Util.debug(f"\t\t_parse_weighted_concept_simple -> {tokens}")
475
+ list_tokens: list[str] = tokens.as_list()
476
+ weight: float = list_tokens[0]
477
+ concept: Concept = DLParser._to_concept(list_tokens[1])
478
+ return pp.ParseResults([WeightedConcept(weight, concept)])
479
+
480
+ @staticmethod
481
+ # @pp.trace_parse_action
482
+ def _parse_weighted_concept(tokens: pp.ParseResults) -> pp.ParseResults:
483
+
484
+ if ConfigReader.DEBUG_PRINT:
485
+ Util.debug(f"\t\t_parse_weighted_concept -> {tokens}")
486
+ list_tokens: list[str] = tokens.as_list()
487
+ operator: str = list_tokens[0]
488
+ assert all(isinstance(c, WeightedConcept) for c in list_tokens[1:])
489
+ weights: list[float] = list(map(lambda x: x.weight, list_tokens[1:]))
490
+ concepts: list[Concept] = [
491
+ DLParser._to_concept(w_concept.curr_concept)
492
+ for w_concept in list_tokens[1:]
493
+ ]
494
+ if operator == FuzzyDLKeyword.W_SUM:
495
+ if not (sum(weights) <= 1.0):
248
496
  Util.error(
249
- "Error: ZADEH_IMPLIES cannot be used under classical reasoner."
497
+ "Error: The sum of the weights must be lower than or equal to 1."
250
498
  )
251
- elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
499
+ return pp.ParseResults([WeightedSumConcept(weights, concepts)])
500
+ elif operator == FuzzyDLKeyword.W_MAX:
501
+ if max(weights) != 1.0:
502
+ Util.error("Error: The maximum of the weights must be equal to 1.")
503
+ return pp.ParseResults([WeightedMaxConcept(weights, concepts)])
504
+ elif operator == FuzzyDLKeyword.W_MIN:
505
+ if max(weights) != 1.0:
506
+ Util.error("Error: The maximum of the weights must be equal to 1.")
507
+ return pp.ParseResults([WeightedMinConcept(weights, concepts)])
508
+ elif operator == FuzzyDLKeyword.W_SUM_ZERO:
509
+ if not (sum(weights) <= 1.0):
252
510
  Util.error(
253
- "Error: KLEENE_DIENES_IMPLIES cannot be used under classical reasoner."
511
+ "Error: The sum of the weights must be lower than or equal to 1."
254
512
  )
255
- if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
256
- return pp.ParseResults(
257
- [ImpliesConcept.goedel_implies(list_tokens[0], list_tokens[1])]
513
+ return pp.ParseResults([WeightedSumZeroConcept(weights, concepts)])
514
+ return tokens
515
+
516
+ @staticmethod
517
+ # @pp.trace_parse_action
518
+ def _parse_q_owa_concept(tokens: pp.ParseResults) -> pp.ParseResults:
519
+
520
+ if ConfigReader.DEBUG_PRINT:
521
+ Util.debug(f"\t\t_parse_q_owa_concept -> {tokens}")
522
+ list_tokens: list[str] = tokens.as_list()
523
+ f: FuzzyConcreteConcept = DLParser.kb.concrete_concepts.get(list_tokens[0])
524
+ if f is None:
525
+ Util.error(f"Error: Fuzzy concept {f} has to be defined before being used.")
526
+ if not isinstance(f, (RightConcreteConcept, LeftConcreteConcept)):
527
+ Util.error(
528
+ f"Error: Fuzzy concept {f} has to be a right or a linear function."
258
529
  )
259
- elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
260
- return pp.ParseResults(
261
- [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
530
+ concepts: list[Concept] = [
531
+ DLParser._to_concept(concept) for concept in list_tokens[1:]
532
+ ]
533
+ return pp.ParseResults([QowaConcept(f, concepts)])
534
+
535
+ @staticmethod
536
+ # @pp.trace_parse_action
537
+ def _parse_owa_integral_concept(tokens: pp.ParseResults) -> pp.ParseResults:
538
+
539
+ if ConfigReader.DEBUG_PRINT:
540
+ Util.debug(f"\t\t_parse_owa_integral_concept -> {tokens}")
541
+ list_tokens: list[str] = tokens.as_list()
542
+ operator: str = list_tokens[0]
543
+ length: int = len(list_tokens) - 1
544
+ assert length % 2 == 0
545
+ weights: list[float] = list_tokens[1:][: length // 2]
546
+ concepts: list[Concept] = [
547
+ DLParser._to_concept(concept) for concept in list_tokens[1:][length // 2 :]
548
+ ]
549
+ if operator == FuzzyDLKeyword.OWA:
550
+ if sum(weights) != 1.0:
551
+ Util.error("Error: The sum of the weights must be equal to 1.")
552
+ return pp.ParseResults([OwaConcept(weights, concepts)])
553
+ elif operator == FuzzyDLKeyword.CHOQUET:
554
+ if max(weights) != 1.0:
555
+ Util.error("Error: The maximum of the weights must be equal to 1.")
556
+ return pp.ParseResults([ChoquetIntegral(weights, concepts)])
557
+ elif operator == FuzzyDLKeyword.SUGENO:
558
+ if max(weights) != 1.0:
559
+ Util.error("Error: The maximum of the weights must be equal to 1.")
560
+ return pp.ParseResults([SugenoIntegral(weights, concepts)])
561
+ elif operator == FuzzyDLKeyword.QUASI_SUGENO:
562
+ if max(weights) != 1.0:
563
+ Util.error("Error: The maximum of the weights must be equal to 1.")
564
+ return pp.ParseResults([QsugenoIntegral(weights, concepts)])
565
+ return tokens
566
+
567
+ @staticmethod
568
+ # @pp.trace_parse_action
569
+ def _parse_modifier(tokens: pp.ParseResults) -> pp.ParseResults:
570
+
571
+ if ConfigReader.DEBUG_PRINT:
572
+ Util.debug(f"\t\t_parse_modifier -> {tokens}")
573
+
574
+ list_tokens: list[str] = tokens.as_list()
575
+ if list_tokens[1] == FuzzyDLKeyword.LINEAR_MODIFIER:
576
+ DLParser.kb.add_modifier(
577
+ list_tokens[0], LinearModifier(list_tokens[0], list_tokens[2])
262
578
  )
263
- elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
264
- return pp.ParseResults(
265
- [ImpliesConcept.kleene_dienes_implies(list_tokens[0], list_tokens[1])]
579
+ elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR_MODIFIER:
580
+ DLParser.kb.add_modifier(
581
+ list_tokens[0],
582
+ TriangularModifier(
583
+ list_tokens[0], list_tokens[2], list_tokens[3], list_tokens[4]
584
+ ),
266
585
  )
267
- return pp.ParseResults(
268
- [ImpliesConcept.lukasiewicz_implies(list_tokens[0], list_tokens[1])]
269
- )
270
- elif operator == FuzzyDLKeyword.ALL:
271
- role: str = list_tokens[1]
272
- concept: Concept = _to_concept(kb, list_tokens[2])
273
- kb.check_role(role, concept)
274
- return pp.ParseResults([AllSomeConcept.all(role, concept)])
275
- elif operator == FuzzyDLKeyword.SOME:
276
- c: Concept = _to_concept(kb, list_tokens[2])
277
- role: str = list_tokens[1]
278
- kb.check_role(role, c)
279
- return pp.ParseResults([AllSomeConcept.some(role, c)])
280
- elif operator == FuzzyDLKeyword.HAS_VALUE:
281
- ind: Individual = kb.get_individual(list_tokens[2])
282
- kb.check_role(role, TruthConcept.get_top())
283
- return pp.ParseResults([HasValueConcept.has_value(role, ind)])
284
- elif operator in (
285
- FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION,
286
- FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION,
287
- FuzzyDLKeyword.UPPER_APPROXIMATION,
288
- FuzzyDLKeyword.LOWER_APPROXIMATION,
289
- FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION,
290
- FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION,
291
- ):
292
- role: str = list_tokens[1]
293
- concept: Concept = _to_concept(kb, list_tokens[2])
294
- if role not in kb.similarity_relations:
295
- Util.error(f"Error: Similarity relation {role} has not been defined.")
296
- if operator == FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION:
297
- return pp.ParseResults(
298
- [ApproximationConcept.tight_upper_approx(role, concept)]
586
+ return tokens
587
+
588
+ @staticmethod
589
+ # @pp.trace_parse_action
590
+ def _parse_truth_constants(tokens: pp.ParseResults) -> pp.ParseResults:
591
+
592
+ if ConfigReader.DEBUG_PRINT:
593
+ Util.debug(f"\t\t_parse_truth_constants -> {tokens}")
594
+ list_tokens: list[str] = tokens.as_list()
595
+ DLParser.kb.set_truth_constants(list_tokens[0], list_tokens[1])
596
+ return tokens
597
+
598
+ @staticmethod
599
+ # @pp.trace_parse_action
600
+ def _parse_fuzzy_concept(tokens: pp.ParseResults) -> pp.ParseResults:
601
+
602
+ if ConfigReader.DEBUG_PRINT:
603
+ Util.debug(f"\t\t_parse_fuzzy_concept -> {tokens}")
604
+ list_tokens: list = tokens.as_list()
605
+ if DLParser.kb.concrete_concepts.get(list_tokens[0]) is not None:
606
+ Util.error(
607
+ f"Error: Fuzzy concept {list_tokens[0]} has to be defined before being used."
299
608
  )
300
- elif operator == FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION:
301
- return pp.ParseResults(
302
- [ApproximationConcept.tight_lower_approx(role, concept)]
609
+ if (
610
+ list_tokens[1] != FuzzyDLKeyword.CRISP
611
+ and DLParser.kb.get_logic() == FuzzyLogic.CLASSICAL
612
+ ):
613
+ Util.error(
614
+ f"Error: Fuzzy concept {list_tokens[0]} cannot be used with the classical reasoner."
303
615
  )
304
- elif operator == FuzzyDLKeyword.UPPER_APPROXIMATION:
305
- return pp.ParseResults([ApproximationConcept.upper_approx(role, concept)])
306
- elif operator == FuzzyDLKeyword.LOWER_APPROXIMATION:
307
- return pp.ParseResults([ApproximationConcept.lower_approx(role, concept)])
308
- elif operator == FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION:
309
- return pp.ParseResults(
310
- [ApproximationConcept.loose_upper_approx(role, concept)]
616
+ if list_tokens[1] == FuzzyDLKeyword.CRISP:
617
+ DLParser.kb.add_concept(
618
+ list_tokens[0],
619
+ CrispConcreteConcept(
620
+ list_tokens[0],
621
+ list_tokens[2],
622
+ list_tokens[3],
623
+ list_tokens[4],
624
+ list_tokens[5],
625
+ ),
311
626
  )
312
- elif operator == FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION:
313
- return pp.ParseResults(
314
- [ApproximationConcept.loose_lower_approx(role, concept)]
627
+ elif list_tokens[1] == FuzzyDLKeyword.LEFT_SHOULDER:
628
+ DLParser.kb.add_concept(
629
+ list_tokens[0],
630
+ LeftConcreteConcept(
631
+ list_tokens[0],
632
+ list_tokens[2],
633
+ list_tokens[3],
634
+ list_tokens[4],
635
+ list_tokens[5],
636
+ ),
315
637
  )
316
- return tokens
638
+ DLParser.kb.concrete_fuzzy_concepts = True
639
+ elif list_tokens[1] == FuzzyDLKeyword.RIGHT_SHOULDER:
640
+ DLParser.kb.add_concept(
641
+ list_tokens[0],
642
+ RightConcreteConcept(
643
+ list_tokens[0],
644
+ list_tokens[2],
645
+ list_tokens[3],
646
+ list_tokens[4],
647
+ list_tokens[5],
648
+ ),
649
+ )
650
+ DLParser.kb.concrete_fuzzy_concepts = True
651
+ elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR:
652
+ DLParser.kb.add_concept(
653
+ list_tokens[0],
654
+ TriangularConcreteConcept(
655
+ list_tokens[0],
656
+ list_tokens[2],
657
+ list_tokens[3],
658
+ list_tokens[4],
659
+ list_tokens[5],
660
+ list_tokens[6],
661
+ ),
662
+ )
663
+ DLParser.kb.concrete_fuzzy_concepts = True
664
+ elif list_tokens[1] == FuzzyDLKeyword.TRAPEZOIDAL:
665
+ DLParser.kb.add_concept(
666
+ list_tokens[0],
667
+ TrapezoidalConcreteConcept(
668
+ list_tokens[0],
669
+ list_tokens[2],
670
+ list_tokens[3],
671
+ list_tokens[4],
672
+ list_tokens[5],
673
+ list_tokens[6],
674
+ list_tokens[7],
675
+ ),
676
+ )
677
+ DLParser.kb.concrete_fuzzy_concepts = True
678
+ elif list_tokens[1] == FuzzyDLKeyword.LINEAR:
679
+ DLParser.kb.add_concept(
680
+ list_tokens[0],
681
+ LinearConcreteConcept(
682
+ list_tokens[0],
683
+ list_tokens[2],
684
+ list_tokens[3],
685
+ list_tokens[4],
686
+ list_tokens[5],
687
+ ),
688
+ )
689
+ DLParser.kb.concrete_fuzzy_concepts = True
690
+ elif list_tokens[1] == FuzzyDLKeyword.MODIFIED:
691
+ mod: Modifier = DLParser._get_modifier(list_tokens[2])
692
+ if DLParser.kb.concrete_concepts.get(list_tokens[3]) is None:
693
+ Util.error(
694
+ f"Error: Fuzzy concept {list_tokens[3]} has to be defined before being used."
695
+ )
696
+ DLParser.kb.add_concept(
697
+ list_tokens[0],
698
+ ModifiedConcreteConcept(
699
+ list_tokens[0],
700
+ mod,
701
+ DLParser.kb.concrete_concepts.get(list_tokens[3]),
702
+ ),
703
+ )
704
+ DLParser.kb.concrete_fuzzy_concepts = True
705
+ return tokens
317
706
 
707
+ @staticmethod
708
+ # @pp.trace_parse_action
709
+ def _parse_fuzzy_number_range(tokens: pp.ParseResults) -> pp.ParseResults:
318
710
 
319
- def _parse_unary_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
320
- if ConfigReader.DEBUG_PRINT:
321
- Util.debug(f"\t\t_parse_unary_concept -> {tokens}")
322
- list_tokens: list[str] = tokens.as_list()
323
- operator: str = list_tokens[0]
324
- if operator == FuzzyDLKeyword.NOT:
325
- concept: Concept = _to_concept(kb, list_tokens[1])
326
- return pp.ParseResults([-concept])
327
- elif operator == FuzzyDLKeyword.SELF:
328
- role: str = list_tokens[1]
329
- if role in kb.concrete_roles:
330
- Util.error(f"Error: Role {role} cannot be concrete and abstract.")
331
- kb.abstract_roles.add(role)
332
- return pp.ParseResults([SelfConcept.self(role)])
333
- return tokens
334
-
335
-
336
- def _parse_modifier_concept(
337
- kb: KnowledgeBase, tokens: pp.ParseResults
338
- ) -> pp.ParseResults:
339
- if ConfigReader.DEBUG_PRINT:
340
- Util.debug(f"\t\t_parse_modifier_concept -> {tokens}")
341
- list_tokens: list[str] = tokens.as_list()
342
- mod: Modifier = _get_modifier(kb, list_tokens[0])
343
- concept: Concept = _to_concept(kb, list_tokens[1])
344
- return pp.ParseResults([mod.modify(concept)])
345
-
346
-
347
- def _parse_threshold_concept(kb: KnowledgeBase, tokens: pp.ParseResults):
348
- if ConfigReader.DEBUG_PRINT:
349
- Util.debug(f"\t\t_parse_threshold_concept -> {tokens}")
350
- list_tokens: list[str] = tokens.as_list()
351
- operator: str = list_tokens[0]
352
- concept: Concept = _to_concept(kb, list_tokens[2])
353
- _check_abstract(concept)
354
- if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
355
- if isinstance(list_tokens[1], (int, float)):
711
+ if ConfigReader.DEBUG_PRINT:
712
+ Util.debug(f"\t\t_parse_fuzzy_number_range -> {tokens}")
713
+ tokens = tokens.as_list()
714
+ TriangularFuzzyNumber.set_range(tokens[0], tokens[1])
715
+ return pp.ParseResults(tokens)
716
+
717
+ @staticmethod
718
+ # @pp.trace_parse_action
719
+ def _create_fuzzy_number(tokens: pp.ParseResults) -> pp.ParseResults:
720
+
721
+ if ConfigReader.DEBUG_PRINT:
722
+ Util.debug(f"\t\t_create_fuzzy_number -> {tokens}")
723
+ tokens = tokens.as_list()
724
+ if len(tokens) == 1:
725
+ if isinstance(tokens[0], (int, float)):
726
+ return pp.ParseResults(
727
+ [TriangularFuzzyNumber(tokens[0], tokens[0], tokens[0])]
728
+ )
729
+ elif tokens[0] == str:
730
+ if tokens[0] not in DLParser.kb.fuzzy_numbers:
731
+ Util.error(
732
+ f"Error: Fuzzy number {tokens[0]} has to be defined before being used."
733
+ )
734
+ return pp.ParseResults([DLParser.kb.fuzzy_numbers.get(tokens[0])])
735
+ elif all(isinstance(t, (int, float)) for t in tokens):
356
736
  return pp.ParseResults(
357
- [ThresholdConcept.pos_threshold(list_tokens[1], concept)]
737
+ [TriangularFuzzyNumber(tokens[0], tokens[1], tokens[2])]
358
738
  )
359
- elif isinstance(list_tokens[1], str):
360
- return pp.ParseResults(
361
- [
362
- ExtThresholdConcept.extended_pos_threshold(
363
- kb.milp.get_variable(list_tokens[1]), concept
364
- )
365
- ]
739
+ return pp.ParseResults(tokens)
740
+
741
+ @staticmethod
742
+ # @pp.trace_parse_action
743
+ def _set_fuzzy_number(tokens: pp.ParseResults) -> pp.ParseResults:
744
+
745
+ if ConfigReader.DEBUG_PRINT:
746
+ Util.debug(f"\t\t_set_fuzzy_number -> {tokens}")
747
+ tokens = tokens.as_list()
748
+ if tokens[0] in DLParser.kb.fuzzy_numbers:
749
+ Util.error(f"Error: Fuzzy number {tokens[0]} has already been defined.")
750
+ for i in range(2, len(tokens)):
751
+ if isinstance(tokens[i], str):
752
+ tokens[i] = DLParser.kb.fuzzy_numbers.get(tokens[i])
753
+ if isinstance(tokens[1], TriangularFuzzyNumber):
754
+ DLParser.kb.add_fuzzy_number(tokens[0], tokens[1])
755
+ DLParser.kb.concrete_fuzzy_concepts = True
756
+ return pp.ParseResults([tokens[1]])
757
+ elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUM, FuzzyDLKeyword.FEATURE_MUL):
758
+ ts: TriangularFuzzyNumber = [
759
+ typing.cast(TriangularFuzzyNumber, t) for t in tokens[2:]
760
+ ]
761
+ result: TriangularFuzzyNumber = reduce(
762
+ (
763
+ TriangularFuzzyNumber.add
764
+ if tokens[1] == FuzzyDLKeyword.FEATURE_SUM
765
+ else TriangularFuzzyNumber.times
766
+ ),
767
+ ts,
366
768
  )
367
- elif operator == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
368
- if isinstance(list_tokens[1], (int, float)):
369
- return pp.ParseResults(
370
- [ThresholdConcept.neg_threshold(list_tokens[1], concept)]
769
+ DLParser.kb.add_fuzzy_number(
770
+ tokens[0],
771
+ result,
371
772
  )
372
- elif isinstance(list_tokens[1], str):
373
- return pp.ParseResults(
374
- [
375
- ExtThresholdConcept.extended_neg_threshold(
376
- kb.milp.get_variable(list_tokens[1]), concept
377
- )
378
- ]
773
+ DLParser.kb.concrete_fuzzy_concepts = True
774
+ return pp.ParseResults([result])
775
+ elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUB, FuzzyDLKeyword.FEATURE_DIV):
776
+ t1: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[2])
777
+ t2: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[3])
778
+ result: TriangularFuzzyNumber = (
779
+ t1 - t2 if tokens[1] == FuzzyDLKeyword.FEATURE_SUB else t1 / t2
379
780
  )
380
- elif operator == FuzzyDLKeyword.EQUALS:
381
- if isinstance(list_tokens[1], (int, float)):
382
- return pp.ParseResults([ThresholdConcept.ea(list_tokens[1], concept)])
383
- elif isinstance(list_tokens[1], str):
384
- return pp.ParseResults(
385
- [
386
- ExtThresholdConcept.extended_neg_threshold(
387
- kb.milp.get_variable(list_tokens[1]), concept
388
- )
389
- ]
781
+ DLParser.kb.add_fuzzy_number(
782
+ tokens[0],
783
+ result,
390
784
  )
391
- return tokens
392
-
393
-
394
- def _parse_weighted_concept_simple(
395
- kb: KnowledgeBase, tokens: pp.ParseResults
396
- ) -> pp.ParseResults:
397
- if ConfigReader.DEBUG_PRINT:
398
- Util.debug(f"\t\t_parse_weighted_concept_simple -> {tokens}")
399
- list_tokens: list[str] = tokens.as_list()
400
- weight: float = list_tokens[0]
401
- concept: Concept = _to_concept(kb, list_tokens[1])
402
- return pp.ParseResults([WeightedConcept(weight, concept)])
403
-
404
-
405
- def _parse_weighted_concept(
406
- kb: KnowledgeBase, tokens: pp.ParseResults
407
- ) -> pp.ParseResults:
408
- if ConfigReader.DEBUG_PRINT:
409
- Util.debug(f"\t\t_parse_weighted_concept -> {tokens}")
410
- list_tokens: list[str] = tokens.as_list()
411
- operator: str = list_tokens[0]
412
- assert all(isinstance(c, WeightedConcept) for c in list_tokens[1:])
413
- weights: list[float] = list(map(lambda x: x.weight, list_tokens[1:]))
414
- if sum(weights) != 1.0:
415
- Util.error("Error: The sum of the weights must be equal to 1.")
416
- concepts: list[Concept] = [
417
- _to_concept(kb, w_concept.curr_concept) for w_concept in list_tokens[1:]
418
- ]
419
- if operator == FuzzyDLKeyword.W_SUM:
420
- return pp.ParseResults([WeightedSumConcept(weights, concepts)])
421
- elif operator == FuzzyDLKeyword.W_MAX:
422
- return pp.ParseResults([WeightedMaxConcept(weights, concepts)])
423
- elif operator == FuzzyDLKeyword.W_MIN:
424
- return pp.ParseResults([WeightedMinConcept(weights, concepts)])
425
- elif operator == FuzzyDLKeyword.W_SUM_ZERO:
426
- return pp.ParseResults([WeightedSumZeroConcept(weights, concepts)])
427
- return tokens
428
-
429
-
430
- def _parse_q_owa_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
431
- if ConfigReader.DEBUG_PRINT:
432
- Util.debug(f"\t\t_parse_q_owa_concept -> {tokens}")
433
- list_tokens: list[str] = tokens.as_list()
434
- f: FuzzyConcreteConcept = kb.concrete_concepts.get(list_tokens[0])
435
- if f is None:
436
- Util.error(f"Error: Fuzzy concept {f} has to be defined before being used.")
437
- if not isinstance(f, (RightConcreteConcept, LeftConcreteConcept)):
438
- Util.error(f"Error: Fuzzy concept {f} has to be a right or a linear function.")
439
- concepts: list[Concept] = [_to_concept(kb, concept) for concept in list_tokens[1:]]
440
- return pp.ParseResults([QowaConcept(f, concepts)])
441
-
442
-
443
- def _parse_owa_integral_concept(
444
- kb: KnowledgeBase, tokens: pp.ParseResults
445
- ) -> pp.ParseResults:
446
- if ConfigReader.DEBUG_PRINT:
447
- Util.debug(f"\t\t_parse_owa_integral_concept -> {tokens}")
448
- list_tokens: list[str] = tokens.as_list()
449
- operator: str = list_tokens[0]
450
- length: int = len(list_tokens) - 1
451
- assert length % 2 == 0
452
- weights: list[float] = list_tokens[1:][: length // 2]
453
- concepts: list[Concept] = [
454
- _to_concept(kb, concept) for concept in list_tokens[1:][length // 2 :]
455
- ]
456
- if operator == FuzzyDLKeyword.OWA:
457
- return pp.ParseResults([OwaConcept(weights, concepts)])
458
- elif operator == FuzzyDLKeyword.CHOQUET:
459
- return pp.ParseResults([ChoquetIntegral(weights, concepts)])
460
- elif operator == FuzzyDLKeyword.SUGENO:
461
- return pp.ParseResults([SugenoIntegral(weights, concepts)])
462
- elif operator == FuzzyDLKeyword.QUASI_SUGENO:
463
- return pp.ParseResults([QsugenoIntegral(weights, concepts)])
464
- return tokens
465
-
466
-
467
- def _parse_modifier(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
468
- if ConfigReader.DEBUG_PRINT:
469
- Util.debug(f"\t\t_parse_modifier -> {tokens}")
470
-
471
- list_tokens: list[str] = tokens.as_list()
472
- if list_tokens[1] == FuzzyDLKeyword.LINEAR_MODIFIER:
473
- kb.add_modifier(list_tokens[0], LinearModifier(list_tokens[0], list_tokens[2]))
474
- elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR_MODIFIER:
475
- kb.add_modifier(
476
- list_tokens[0],
477
- TriangularModifier(
478
- list_tokens[0], list_tokens[2], list_tokens[3], list_tokens[4]
479
- ),
480
- )
481
- return tokens
482
-
483
-
484
- def _parse_truth_constants(
485
- kb: KnowledgeBase, tokens: pp.ParseResults
486
- ) -> pp.ParseResults:
487
- if ConfigReader.DEBUG_PRINT:
488
- Util.debug(f"\t\t_parse_truth_constants -> {tokens}")
489
- list_tokens: list[str] = tokens.as_list()
490
- kb.set_truth_constants(list_tokens[0], list_tokens[1])
491
- return tokens
492
-
493
-
494
- def _parse_fuzzy_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
495
- if ConfigReader.DEBUG_PRINT:
496
- Util.debug(f"\t\t_parse_fuzzy_concept -> {tokens}")
497
- list_tokens: list = tokens.as_list()
498
- if kb.concrete_concepts.get(list_tokens[0]) is not None:
499
- Util.error(
500
- f"Error: Fuzzy concept {list_tokens[0]} has to be defined before being used."
501
- )
502
- if (
503
- list_tokens[1] != FuzzyDLKeyword.CRISP
504
- and kb.get_logic() == FuzzyLogic.CLASSICAL
505
- ):
506
- Util.error(
507
- f"Error: Fuzzy concept {list_tokens[0]} cannot be used with the classical reasoner."
508
- )
509
- if list_tokens[1] == FuzzyDLKeyword.CRISP:
510
- kb.add_concept(
511
- list_tokens[0],
512
- CrispConcreteConcept(
513
- list_tokens[0],
514
- list_tokens[2],
515
- list_tokens[3],
516
- list_tokens[4],
517
- list_tokens[5],
518
- ),
519
- )
520
- elif list_tokens[1] == FuzzyDLKeyword.LEFT_SHOULDER:
521
- kb.add_concept(
522
- list_tokens[0],
523
- LeftConcreteConcept(
524
- list_tokens[0],
525
- list_tokens[2],
526
- list_tokens[3],
527
- list_tokens[4],
528
- list_tokens[5],
529
- ),
530
- )
531
- kb.concrete_fuzzy_concepts = True
532
- elif list_tokens[1] == FuzzyDLKeyword.RIGHT_SHOULDER:
533
- kb.add_concept(
534
- list_tokens[0],
535
- RightConcreteConcept(
536
- list_tokens[0],
537
- list_tokens[2],
538
- list_tokens[3],
539
- list_tokens[4],
540
- list_tokens[5],
541
- ),
542
- )
543
- kb.concrete_fuzzy_concepts = True
544
- elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR:
545
- kb.add_concept(
546
- list_tokens[0],
547
- TriangularConcreteConcept(
548
- list_tokens[0],
549
- list_tokens[2],
550
- list_tokens[3],
551
- list_tokens[4],
552
- list_tokens[5],
553
- list_tokens[6],
554
- ),
555
- )
556
- kb.concrete_fuzzy_concepts = True
557
- elif list_tokens[1] == FuzzyDLKeyword.TRAPEZOIDAL:
558
- kb.add_concept(
559
- list_tokens[0],
560
- TrapezoidalConcreteConcept(
561
- list_tokens[0],
562
- list_tokens[2],
563
- list_tokens[3],
564
- list_tokens[4],
565
- list_tokens[5],
566
- list_tokens[6],
567
- list_tokens[7],
568
- ),
569
- )
570
- kb.concrete_fuzzy_concepts = True
571
- elif list_tokens[1] == FuzzyDLKeyword.LINEAR:
572
- kb.add_concept(
573
- list_tokens[0],
574
- LinearConcreteConcept(
575
- list_tokens[0],
576
- list_tokens[2],
577
- list_tokens[3],
578
- list_tokens[4],
579
- list_tokens[5],
580
- ),
581
- )
582
- kb.concrete_fuzzy_concepts = True
583
- elif list_tokens[1] == FuzzyDLKeyword.MODIFIED:
584
- mod: Modifier = _get_modifier(kb, list_tokens[2])
585
- if kb.concrete_concepts.get(list_tokens[3]) is None:
586
- Util.error(
587
- f"Error: Fuzzy concept {list_tokens[3]} has to be defined before being used."
785
+ DLParser.kb.concrete_fuzzy_concepts = True
786
+ return pp.ParseResults([result])
787
+ return pp.ParseResults(tokens)
788
+
789
+ @staticmethod
790
+ # @pp.trace_parse_action
791
+ def _parse_feature(tokens: pp.ParseResults) -> pp.ParseResults:
792
+
793
+ if ConfigReader.DEBUG_PRINT:
794
+ Util.debug(f"\t\t_parse_feature -> {tokens}")
795
+ tokens = tokens.as_list()
796
+ role: str = tokens[1]
797
+ if tokens[2] == FuzzyDLKeyword.INTEGER:
798
+ DLParser.kb.define_integer_concrete_feature(
799
+ role, int(tokens[3]), int(tokens[4])
588
800
  )
589
- kb.add_concept(
590
- list_tokens[0],
591
- ModifiedConcreteConcept(
592
- list_tokens[0],
593
- mod,
594
- kb.concrete_concepts.get(list_tokens[3]),
595
- ),
596
- )
597
- kb.concrete_fuzzy_concepts = True
598
- return tokens
599
-
600
-
601
- def _parse_fuzzy_number_range(
602
- kb: KnowledgeBase, tokens: pp.ParseResults
603
- ) -> pp.ParseResults:
604
- if ConfigReader.DEBUG_PRINT:
605
- Util.debug(f"\t\t_parse_fuzzy_number_range -> {tokens}")
606
- tokens = tokens.as_list()
607
- TriangularFuzzyNumber.set_range(tokens[0], tokens[1])
608
- return pp.ParseResults(tokens)
609
-
610
-
611
- def _create_fuzzy_number(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
612
- if ConfigReader.DEBUG_PRINT:
613
- Util.debug(f"\t\t_create_fuzzy_number -> {tokens}")
614
- tokens = tokens.as_list()
615
- if len(tokens) == 1:
616
- if isinstance(tokens[0], (int, float)):
801
+ elif tokens[2] == FuzzyDLKeyword.REAL:
802
+ DLParser.kb.define_real_concrete_feature(
803
+ role, float(tokens[3]), float(tokens[4])
804
+ )
805
+ elif tokens[2] == FuzzyDLKeyword.BOOLEAN:
806
+ DLParser.kb.define_boolean_concrete_feature(role)
807
+ elif tokens[2] == FuzzyDLKeyword.STRING:
808
+ DLParser.kb.define_string_concrete_feature(role)
809
+ return pp.ParseResults(tokens)
810
+
811
+ def _parse_restrictions(tokens: pp.ParseResults) -> typing.Any:
812
+
813
+ if ConfigReader.DEBUG_PRINT:
814
+ Util.debug(f"\t\t_parse_restrictions -> {tokens}")
815
+ tokens = tokens.as_list()
816
+ if isinstance(tokens[0], (list, tuple)):
817
+ tokens = tokens[0]
818
+ if len(tokens) == 1:
819
+ if isinstance(tokens[0], str) or isinstance(tokens[0], constants.NUMBER):
820
+ return pp.ParseResults([FeatureFunction(tokens[0])])
821
+ elif len(tokens) == 2 and isinstance(tokens[0], (int, float)):
617
822
  return pp.ParseResults(
618
- [TriangularFuzzyNumber(tokens[0], tokens[0], tokens[0])]
823
+ [FeatureFunction(tokens[0], FeatureFunction(tokens[1]))]
619
824
  )
620
- elif tokens[0] == str:
621
- if tokens[0] not in kb.fuzzy_numbers:
622
- Util.error(
623
- f"Error: Fuzzy number {tokens[0]} has to be defined before being used."
825
+ elif len(tokens) >= 3:
826
+ if FuzzyDLKeyword.MUL.get_value() in tokens:
827
+ return pp.ParseResults(
828
+ [FeatureFunction(tokens[0], FeatureFunction(tokens[2]))]
624
829
  )
625
- return pp.ParseResults([kb.fuzzy_numbers.get(tokens[0])])
626
- elif all(isinstance(t, (int, float)) for t in tokens):
627
- return pp.ParseResults([TriangularFuzzyNumber(tokens[0], tokens[1], tokens[2])])
628
- return pp.ParseResults(tokens)
629
-
630
-
631
- def _set_fuzzy_number(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
632
- if ConfigReader.DEBUG_PRINT:
633
- Util.debug(f"\t\t_set_fuzzy_number -> {tokens}")
634
- tokens = tokens.as_list()
635
- if tokens[0] in kb.fuzzy_numbers:
636
- Util.error(f"Error: Fuzzy number {tokens[0]} has already been defined.")
637
- if isinstance(tokens[1], TriangularFuzzyNumber):
638
- kb.add_fuzzy_number(tokens[0], tokens[1])
639
- kb.concrete_fuzzy_concepts = True
640
- return pp.ParseResults([tokens[1]])
641
- elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUM, FuzzyDLKeyword.FEATURE_MUL):
642
- ts: TriangularFuzzyNumber = [
643
- typing.cast(TriangularFuzzyNumber, t) for t in tokens[2:]
644
- ]
645
- result: TriangularFuzzyNumber = reduce(
646
- (
647
- TriangularFuzzyNumber.add
648
- if tokens[1] == FuzzyDLKeyword.FEATURE_SUM
649
- else TriangularFuzzyNumber.times
650
- ),
651
- ts,
652
- )
653
- kb.add_fuzzy_number(
654
- tokens[0],
655
- result,
656
- )
657
- kb.concrete_fuzzy_concepts = True
658
- return pp.ParseResults([result])
659
- elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUB, FuzzyDLKeyword.FEATURE_DIV):
660
- t1: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[2])
661
- t2: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[3])
662
- result: TriangularFuzzyNumber = (
663
- t1.minus(t2)
664
- if tokens[1] == FuzzyDLKeyword.FEATURE_SUB
665
- else t1.divided_by(t2)
666
- )
667
- kb.add_fuzzy_number(
668
- tokens[0],
669
- result,
670
- )
671
- kb.concrete_fuzzy_concepts = True
672
- return pp.ParseResults([result])
673
- return pp.ParseResults(tokens)
674
-
675
-
676
- def _parse_feature(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
677
- if ConfigReader.DEBUG_PRINT:
678
- Util.debug(f"\t\t_parse_feature -> {tokens}")
679
- tokens = tokens.as_list()
680
- role: str = tokens[1]
681
- if tokens[2] == FuzzyDLKeyword.INTEGER:
682
- kb.define_integer_concrete_feature(role, int(tokens[3]), int(tokens[4]))
683
- elif tokens[2] == FuzzyDLKeyword.REAL:
684
- kb.define_real_concrete_feature(role, float(tokens[3]), float(tokens[4]))
685
- elif tokens[2] == FuzzyDLKeyword.BOOLEAN:
686
- kb.define_boolean_concrete_feature(role)
687
- elif tokens[2] == FuzzyDLKeyword.STRING:
688
- kb.define_string_concrete_feature(role)
689
- return pp.ParseResults(tokens)
690
-
691
-
692
- def _parse_restrictions(kb: KnowledgeBase, tokens: pp.ParseResults) -> typing.Any:
693
- if ConfigReader.DEBUG_PRINT:
694
- Util.debug(f"\t\t_parse_restrictions -> {tokens}")
695
- tokens = tokens.as_list()
696
- if len(tokens) == 1:
697
- if isinstance(tokens[0], (str, int, float)):
698
- return FeatureFunction(tokens[0])
699
- elif len(tokens) == 2 and isinstance(tokens[0], (int, float)):
700
- return FeatureFunction(tokens[0], pp.ParseResults([tokens[1]]))
701
- elif len(tokens) == 3:
702
- if isinstance(tokens[0], (int, float)):
703
- return FeatureFunction(tokens[0], FeatureFunction(tokens[2]))
704
- if isinstance(tokens[0], str):
705
- if "-" in tokens:
706
- return FeatureFunction(
707
- FeatureFunction(tokens[0]), FeatureFunction(tokens[2])
830
+ elif FuzzyDLKeyword.SUB.get_value() in tokens:
831
+ return pp.ParseResults(
832
+ [
833
+ FeatureFunction(
834
+ FeatureFunction(tokens[0]), FeatureFunction(tokens[2])
835
+ )
836
+ ]
708
837
  )
709
- elif "+" in tokens:
710
- return FeatureFunction(
711
- FeatureFunction(list(map(FeatureFunction, tokens[::2])))
838
+ elif FuzzyDLKeyword.SUM.get_value() in tokens:
839
+ return pp.ParseResults(
840
+ [FeatureFunction(list(map(FeatureFunction, tokens[::2])))]
712
841
  )
713
- return pp.ParseResults(tokens)
714
-
715
-
716
- def _parse_datatype_restriction(
717
- kb: KnowledgeBase, tokens: pp.ParseResults
718
- ) -> pp.ParseResults:
719
- if ConfigReader.DEBUG_PRINT:
720
- Util.debug(f"\t\t_parse_datatype_restriction -> {tokens}")
721
- list_tokens = tokens.as_list()
722
- role: str = list_tokens[1]
723
- if role not in kb.concrete_features:
724
- Util.error(f"Error: Feature {role} has not been defined.")
725
- restriction_type: RestrictionType = RestrictionType.EXACT_VALUE
726
- if list_tokens[0] == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
727
- restriction_type = RestrictionType.AT_MOST_VALUE
728
- elif list_tokens[0] == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
729
- restriction_type = RestrictionType.AT_LEAST_VALUE
730
- if isinstance(list_tokens[2], str):
731
- if tokens[2].get_name() == "string":
732
- return pp.ParseResults(
733
- [kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
734
- )
735
- else:
736
- if kb.check_fuzzy_number_concept_exists(list_tokens[2]):
842
+ return pp.ParseResults(tokens)
843
+
844
+ @staticmethod
845
+ # @pp.trace_parse_action
846
+ def _parse_datatype_restriction(tokens: pp.ParseResults) -> pp.ParseResults:
847
+
848
+ if ConfigReader.DEBUG_PRINT:
849
+ Util.debug(f"\t\t_parse_datatype_restriction -> {tokens}")
850
+ list_tokens = tokens.as_list()
851
+ role: str = list_tokens[1]
852
+ if role not in DLParser.kb.concrete_features:
853
+ Util.error(f"Error: Feature {role} has not been defined.")
854
+ restriction_type: RestrictionType = RestrictionType.EXACT_VALUE
855
+ if list_tokens[0] == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
856
+ restriction_type = RestrictionType.AT_MOST_VALUE
857
+ elif list_tokens[0] == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
858
+ restriction_type = RestrictionType.AT_LEAST_VALUE
859
+ if isinstance(list_tokens[2], str):
860
+ # if tokens.as_dict().get("string") == tokens[2] and not DLParser.kb.check_fuzzy_number_concept_exists(list_tokens[2]):
861
+ # return pp.ParseResults(
862
+ # [DLParser.kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
863
+ # )
864
+ # else:
865
+ if DLParser.kb.check_fuzzy_number_concept_exists(list_tokens[2]):
737
866
  return pp.ParseResults(
738
867
  [
739
- kb.add_datatype_restriction(
740
- restriction_type, kb.get_concept(list_tokens[2]), role
868
+ DLParser.kb.add_datatype_restriction(
869
+ restriction_type,
870
+ DLParser.kb.get_concept(list_tokens[2]),
871
+ role,
741
872
  )
742
873
  ]
743
874
  )
744
875
  else:
745
876
  v: Variable = Variable(list_tokens[2], VariableType.CONTINUOUS)
746
877
  return pp.ParseResults(
747
- [kb.add_datatype_restriction(restriction_type, v, role)]
878
+ [DLParser.kb.add_datatype_restriction(restriction_type, v, role)]
748
879
  )
749
- elif isinstance(list_tokens[2], TriangularFuzzyNumber):
750
- if not TriangularFuzzyNumber.has_defined_range():
751
- Util.error(
752
- "Error: The range of the fuzzy numbers has to be defined before being used."
753
- )
754
- if list_tokens[2].is_number():
880
+ elif isinstance(list_tokens[2], TriangularFuzzyNumber):
881
+ if not TriangularFuzzyNumber.has_defined_range():
882
+ Util.error(
883
+ "Error: The range of the fuzzy numbers has to be defined before being used."
884
+ )
885
+ if list_tokens[2].is_number():
886
+ return pp.ParseResults(
887
+ [
888
+ DLParser.kb.add_datatype_restriction(
889
+ restriction_type, list_tokens[2].get_a(), role
890
+ )
891
+ ]
892
+ )
893
+ else:
894
+ return pp.ParseResults(
895
+ [
896
+ DLParser.kb.add_datatype_restriction(
897
+ restriction_type, list_tokens[2], role
898
+ )
899
+ ]
900
+ )
901
+ elif isinstance(list_tokens[2], FeatureFunction):
755
902
  return pp.ParseResults(
756
903
  [
757
- kb.add_datatype_restriction(
758
- restriction_type, list_tokens[2].get_a(), role
904
+ DLParser.kb.add_datatype_restriction(
905
+ restriction_type, list_tokens[2], role
759
906
  )
760
907
  ]
761
908
  )
762
- else:
909
+ return tokens
910
+
911
+ @staticmethod
912
+ # @pp.trace_parse_action
913
+ def _parse_term(tokens: pp.ParseResults) -> pp.ParseResults:
914
+
915
+ if ConfigReader.DEBUG_PRINT:
916
+ Util.debug(f"\t\t_parse_term -> {tokens}")
917
+ list_tokens: list = tokens.as_list()[0]
918
+ if len(list_tokens) == 1:
763
919
  return pp.ParseResults(
764
- [kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
920
+ [Term(1.0, DLParser.kb.milp.get_variable(list_tokens[0]))]
765
921
  )
766
- elif isinstance(list_tokens[2], FeatureFunction):
767
- return pp.ParseResults(
768
- [kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
769
- )
770
- return tokens
922
+ elif len(list_tokens) == 3:
923
+ return pp.ParseResults(
924
+ [Term(list_tokens[0], DLParser.kb.milp.get_variable(list_tokens[2]))]
925
+ )
926
+ return tokens
771
927
 
928
+ @staticmethod
929
+ # @pp.trace_parse_action
930
+ def _parse_expression(tokens: pp.ParseResults) -> pp.ParseResults:
772
931
 
773
- def _parse_expression(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
774
- if ConfigReader.DEBUG_PRINT:
775
- Util.debug(f"\t\t_parse_expression -> {tokens}")
776
- list_tokens: list = tokens.as_list()
777
- if "+" in list_tokens and "*" in list_tokens:
778
- list_tokens = [t for t in list_tokens if t not in ("+", "*")]
779
- constants: list[int | float] = list_tokens[::2]
780
- variables: list[int | float] = list_tokens[1::2]
932
+ if ConfigReader.DEBUG_PRINT:
933
+ Util.debug(f"\t\t_parse_expression -> {tokens}")
934
+ list_tokens: list = tokens.as_list()
781
935
  expr: Expression = Expression(0)
782
- for c, v in zip(constants, variables):
783
- expr.add_term(Term(c, v))
784
- return pp.ParseResults([expr])
785
- return tokens
786
-
787
-
788
- def _parse_inequation(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
789
- if ConfigReader.DEBUG_PRINT:
790
- Util.debug(f"\t\t_parse_inequation -> {tokens}")
791
- list_tokens: list = tokens.as_list()
792
- if isinstance(list_tokens[0], Expression):
793
- operator: str = list_tokens[1]
794
- constant: int | float = list_tokens[2]
795
- expr: Expression = list_tokens[0] - constant
796
- operator_type: InequalityType = (
797
- InequalityType.EQUAL
798
- if operator == FuzzyDLKeyword.EQUALS
799
- else (
800
- InequalityType.GREATER_THAN
801
- if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO
802
- else InequalityType.LESS_THAN
936
+ if isinstance(list_tokens[0], (tuple, list)):
937
+ list_tokens = list_tokens[0]
938
+ if len(list_tokens) == 1 and isinstance(list_tokens[0], Term):
939
+ expr.add_term(list_tokens[0])
940
+ return expr
941
+ if "+" in list_tokens and all(
942
+ isinstance(term, Term) for term in list_tokens[::2]
943
+ ):
944
+ for term in list_tokens[::2]:
945
+ expr.add_term(term)
946
+ return pp.ParseResults([expr])
947
+ return tokens
948
+
949
+ @staticmethod
950
+ # @pp.trace_parse_action
951
+ def _parse_inequation(tokens: pp.ParseResults) -> pp.ParseResults:
952
+
953
+ if ConfigReader.DEBUG_PRINT:
954
+ Util.debug(f"\t\t_parse_inequation -> {tokens}")
955
+ list_tokens: list = tokens.as_list()
956
+ if isinstance(list_tokens[0], Expression):
957
+ operator: str = list_tokens[1]
958
+ constant: int | float = list_tokens[2]
959
+ expr: Expression = list_tokens[0] - constant
960
+ operator_type: InequalityType = (
961
+ InequalityType.EQUAL
962
+ if operator == FuzzyDLKeyword.EQUALS
963
+ else (
964
+ InequalityType.GREATER_THAN
965
+ if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO
966
+ else InequalityType.LESS_THAN
967
+ )
803
968
  )
804
- )
805
- kb.milp.add_new_constraint(expr, operator_type)
806
- return tokens
807
-
808
-
809
- def _parse_constraints(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
810
- if ConfigReader.DEBUG_PRINT:
811
- Util.debug(f"\t\t_parse_constraints -> {tokens}")
812
- list_tokens: list = tokens.as_list()
813
- if list_tokens[0] == FuzzyDLKeyword.BINARY:
814
- v: Variable = kb.milp.get_variable(list_tokens[1])
815
- v.set_type(VariableType.BINARY)
816
- elif list_tokens[0] == FuzzyDLKeyword.FREE:
817
- v: Variable = kb.milp.get_variable(list_tokens[1])
818
- v.set_type(VariableType.CONTINUOUS)
819
- return tokens
820
-
821
-
822
- def _show_concrete_fillers(
823
- kb: KnowledgeBase, tokens: pp.ParseResults
824
- ) -> pp.ParseResults:
825
- if ConfigReader.DEBUG_PRINT:
826
- Util.debug(f"\t\t_show_concrete_fillers -> {tokens}")
827
- list_tokens: list = tokens.as_list()
828
- for role in list_tokens:
829
- if role in kb.concrete_roles:
830
- kb.milp.show_vars.add_concrete_filler_to_show(role)
831
- else:
969
+ DLParser.kb.milp.add_new_constraint(expr, operator_type)
970
+ return pp.ParseResults([Inequation(expr, operator_type)])
971
+ return tokens
972
+
973
+ @staticmethod
974
+ # @pp.trace_parse_action
975
+ def _parse_constraints(tokens: pp.ParseResults) -> pp.ParseResults:
976
+
977
+ if ConfigReader.DEBUG_PRINT:
978
+ Util.debug(f"\t\t_parse_constraints -> {tokens}")
979
+ list_tokens: list = tokens.as_list()
980
+ if list_tokens[0] == FuzzyDLKeyword.BINARY:
981
+ v: Variable = DLParser.kb.milp.get_variable(list_tokens[1])
982
+ v.set_type(VariableType.BINARY)
983
+ elif list_tokens[0] == FuzzyDLKeyword.FREE:
984
+ v: Variable = DLParser.kb.milp.get_variable(list_tokens[1])
985
+ v.set_type(VariableType.CONTINUOUS)
986
+ return tokens
987
+
988
+ @staticmethod
989
+ # @pp.trace_parse_action
990
+ def _show_concrete_fillers(tokens: pp.ParseResults) -> pp.ParseResults:
991
+
992
+ if ConfigReader.DEBUG_PRINT:
993
+ Util.debug(f"\t\t_show_concrete_fillers -> {tokens}")
994
+ list_tokens: list = tokens.as_list()
995
+ for role in list_tokens:
996
+ if role in DLParser.kb.concrete_roles:
997
+ DLParser.kb.milp.show_vars.add_concrete_filler_to_show(role)
998
+ else:
999
+ Util.error(
1000
+ "Error: show-concrete-fillers can only be used with concrete roles."
1001
+ )
1002
+ return tokens
1003
+
1004
+ @staticmethod
1005
+ # @pp.trace_parse_action
1006
+ def _show_concrete_fillers_for(tokens: pp.ParseResults) -> pp.ParseResults:
1007
+
1008
+ if ConfigReader.DEBUG_PRINT:
1009
+ Util.debug(f"\t\t_show_concrete_fillers_for -> {tokens}")
1010
+ list_tokens: list = tokens.as_list()
1011
+ ind_name: str = list_tokens[0]
1012
+ for role in list_tokens[1:]:
1013
+ if role in DLParser.kb.concrete_roles:
1014
+ DLParser.kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name)
1015
+ else:
1016
+ Util.error(
1017
+ "Error: show-concrete-fillers-for can only be used with concrete roles."
1018
+ )
1019
+ return tokens
1020
+
1021
+ @staticmethod
1022
+ # @pp.trace_parse_action
1023
+ def _show_concrete_instance_for(tokens: pp.ParseResults) -> pp.ParseResults:
1024
+
1025
+ if ConfigReader.DEBUG_PRINT:
1026
+ Util.debug(f"\t\t_show_concrete_instance_for -> {tokens}")
1027
+ list_tokens: list = tokens.as_list()
1028
+ ind_name: str = list_tokens[0]
1029
+ role: str = list_tokens[1]
1030
+ if role not in DLParser.kb.concrete_roles:
832
1031
  Util.error(
833
- "Error: show-concrete-fillers can only be used with concrete roles."
1032
+ "Error: show-concrete-instance-for can only be used with concrete roles."
834
1033
  )
835
- return tokens
1034
+ ar: list[FuzzyConcreteConcept] = []
1035
+ for c_name in list_tokens[2:]:
1036
+ concept: Concept = DLParser.kb.concrete_concepts.get(c_name)
1037
+ if concept is None:
1038
+ Util.error(
1039
+ f"Error: Concrete fuzzy concept {c_name} has not been defined."
1040
+ )
1041
+ if concept.type not in (ConceptType.CONCRETE, ConceptType.FUZZY_NUMBER):
1042
+ Util.error(f"Error: {c_name} is not a concrete fuzzy concept.")
1043
+ ar.append(typing.cast(FuzzyConcreteConcept, concept))
1044
+ DLParser.kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name, ar)
1045
+ return tokens
836
1046
 
1047
+ @staticmethod
1048
+ # @pp.trace_parse_action
1049
+ def _show_abstract_fillers(tokens: pp.ParseResults) -> pp.ParseResults:
837
1050
 
838
- def _show_concrete_fillers_for(
839
- kb: KnowledgeBase, tokens: pp.ParseResults
840
- ) -> pp.ParseResults:
841
- if ConfigReader.DEBUG_PRINT:
842
- Util.debug(f"\t\t_show_concrete_fillers_for -> {tokens}")
843
- list_tokens: list = tokens.as_list()
844
- ind_name: str = list_tokens[0]
845
- for role in list_tokens[1:]:
846
- if role in kb.concrete_roles:
847
- kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name)
848
- else:
849
- Util.error(
850
- "Error: show-concrete-fillers-for can only be used with concrete roles."
851
- )
852
- return tokens
853
-
854
-
855
- def _show_concrete_instance_for(
856
- kb: KnowledgeBase, tokens: pp.ParseResults
857
- ) -> pp.ParseResults:
858
- if ConfigReader.DEBUG_PRINT:
859
- Util.debug(f"\t\t_show_concrete_instance_for -> {tokens}")
860
- list_tokens: list = tokens.as_list()
861
- ind_name: str = list_tokens[0]
862
- role: str = list_tokens[1]
863
- if role not in kb.concrete_roles:
864
- Util.error(
865
- "Error: show-concrete-instance-for can only be used with concrete roles."
866
- )
867
- ar: list[FuzzyConcreteConcept] = []
868
- for c_name in list_tokens[2:]:
869
- concept: Concept = kb.concrete_concepts.get(c_name)
870
- if concept is None:
871
- Util.error(f"Error: Concrete fuzzy concept {c_name} has not been defined.")
872
- if concept.type not in (ConceptType.CONCRETE, ConceptType.FUZZY_NUMBER):
873
- Util.error(f"Error: {c_name} is not a concrete fuzzy concept.")
874
- ar.append(typing.cast(FuzzyConcreteConcept, concept))
875
- kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name, ar)
876
- return tokens
877
-
878
-
879
- def _show_abstract_fillers(
880
- kb: KnowledgeBase, tokens: pp.ParseResults
881
- ) -> pp.ParseResults:
882
- if ConfigReader.DEBUG_PRINT:
883
- Util.debug(f"\t\t_show_abstract_fillers -> {tokens}")
884
- list_tokens: list = tokens.as_list()
885
- for role in list_tokens:
886
- if role in kb.concrete_roles:
887
- Util.error(
888
- "Error: show-abstract-fillers can only be used with abstract roles."
889
- )
890
- continue
891
- kb.milp.show_vars.add_abstract_filler_to_show(role)
892
- return tokens
893
-
894
-
895
- def _show_abstract_fillers_for(
896
- kb: KnowledgeBase, tokens: pp.ParseResults
897
- ) -> pp.ParseResults:
898
- if ConfigReader.DEBUG_PRINT:
899
- Util.debug(f"\t\t_show_abstract_fillers_for -> {tokens}")
900
- list_tokens: list = tokens.as_list()
901
- ind_name: str = list_tokens[1:]
902
- for role in list_tokens:
903
- if role in kb.concrete_roles:
904
- Util.error(
905
- "Error: show-abstract-fillers-for can only be used with abstract roles."
906
- )
907
- kb.milp.show_vars.add_abstract_filler_to_show(role, ind_name)
908
- return tokens
909
-
910
-
911
- def _show_concepts(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
912
- if ConfigReader.DEBUG_PRINT:
913
- Util.debug(f"\t\t_show_concepts -> {tokens}")
914
- list_tokens: list = tokens.as_list()
915
- for ind_name in list_tokens:
916
- kb.milp.show_vars.add_individual_to_show(ind_name)
917
- return tokens
918
-
919
-
920
- def _show_instances(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
921
- if ConfigReader.DEBUG_PRINT:
922
- Util.debug(f"\t\t_show_instances -> {tokens}")
923
- list_tokens: list = tokens.as_list()
924
- for concept in list_tokens:
925
- concept: Concept = _to_concept(kb, concept)
926
- kb.milp.show_vars.add_concept_to_show(str(concept))
927
- return tokens
928
-
929
-
930
- def _show_variables(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
931
- if ConfigReader.DEBUG_PRINT:
932
- Util.debug(f"\t\t_show_variables -> {tokens}")
933
- list_tokens: list = tokens.as_list()
934
- for variable_name in list_tokens:
935
- var: Variable = kb.milp.get_variable(variable_name)
936
- kb.milp.show_vars.add_variable(var, str(var))
937
- return tokens
938
-
939
-
940
- def _show_languages(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
941
- if ConfigReader.DEBUG_PRINT:
942
- Util.debug(f"\t\t_show_languages -> {tokens}")
943
- kb.show_language = True
944
- return tokens
945
-
946
-
947
- def _parse_crisp_declarations(
948
- kb: KnowledgeBase, tokens: pp.ParseResults
949
- ) -> pp.ParseResults:
950
- if ConfigReader.DEBUG_PRINT:
951
- Util.debug(f"\t\t_parse_crisp_declarations -> {tokens}")
952
- list_tokens: list = tokens.as_list()
953
- if list_tokens[0] == FuzzyDLKeyword.CRISP_CONCEPT:
954
- for concept in list_tokens[1:]:
955
- concept: Concept = _to_concept(kb, concept)
956
- kb.set_crisp_concept(concept)
957
- elif list_tokens[0] == FuzzyDLKeyword.CRISP_ROLE:
958
- for role in list_tokens[1:]:
959
- kb.set_crisp_role(role)
960
- return tokens
961
-
962
-
963
- def _parse_fuzzy_similarity(
964
- kb: KnowledgeBase, tokens: pp.ParseResults
965
- ) -> pp.ParseResults:
966
- if ConfigReader.DEBUG_PRINT:
967
- Util.debug(f"\t\t_parse_fuzzy_similarity -> {tokens}")
968
- list_tokens: list = tokens.as_list()
969
- kb.add_similarity_relation(list_tokens[0])
970
- return tokens
971
-
972
-
973
- def _parse_fuzzy_equivalence(
974
- kb: KnowledgeBase, tokens: pp.ParseResults
975
- ) -> pp.ParseResults:
976
- if ConfigReader.DEBUG_PRINT:
977
- Util.debug(f"\t\t_parse_fuzzy_equivalence -> {tokens}")
978
- list_tokens: list = tokens.as_list()
979
- kb.add_equivalence_relation(list_tokens[0])
980
- return tokens
981
-
982
-
983
- def _parse_degree(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
984
- if ConfigReader.DEBUG_PRINT:
985
- Util.debug(f"\t\t_parse_degree -> {tokens}")
986
-
987
- list_tokens: list = tokens.as_list()
988
- if isinstance(list_tokens[0], (int, float)):
989
- return pp.ParseResults([DegreeNumeric.get_degree(float(list_tokens[0]))])
990
- elif isinstance(list_tokens[0], Expression):
991
- return pp.ParseResults([DegreeExpression.get_degree(list_tokens[0])])
992
- elif isinstance(list_tokens[0], str):
993
- tc: typing.Optional[float] = kb.get_truth_constants(list_tokens[0])
994
- if tc is not None:
995
- return pp.ParseResults([DegreeNumeric.get_degree(float(tc))])
996
- else:
997
- return pp.ParseResults(
998
- [DegreeVariable.get_degree(kb.milp.get_variable(list_tokens[0]))]
1051
+ if ConfigReader.DEBUG_PRINT:
1052
+ Util.debug(f"\t\t_show_abstract_fillers -> {tokens}")
1053
+ list_tokens: list = tokens.as_list()
1054
+ for role in list_tokens:
1055
+ if role in DLParser.kb.concrete_roles:
1056
+ Util.error(
1057
+ "Error: show-abstract-fillers can only be used with abstract roles."
1058
+ )
1059
+ continue
1060
+ DLParser.kb.milp.show_vars.add_abstract_filler_to_show(role)
1061
+ return tokens
1062
+
1063
+ @staticmethod
1064
+ # @pp.trace_parse_action
1065
+ def _show_abstract_fillers_for(tokens: pp.ParseResults) -> pp.ParseResults:
1066
+
1067
+ if ConfigReader.DEBUG_PRINT:
1068
+ Util.debug(f"\t\t_show_abstract_fillers_for -> {tokens}")
1069
+ list_tokens: list = tokens.as_list()
1070
+ ind_name: str = list_tokens[1:]
1071
+ for role in list_tokens:
1072
+ if role in DLParser.kb.concrete_roles:
1073
+ Util.error(
1074
+ "Error: show-abstract-fillers-for can only be used with abstract roles."
1075
+ )
1076
+ DLParser.kb.milp.show_vars.add_abstract_filler_to_show(role, ind_name)
1077
+ return tokens
1078
+
1079
+ @staticmethod
1080
+ # @pp.trace_parse_action
1081
+ def _show_concepts(tokens: pp.ParseResults) -> pp.ParseResults:
1082
+
1083
+ if ConfigReader.DEBUG_PRINT:
1084
+ Util.debug(f"\t\t_show_concepts -> {tokens}")
1085
+ list_tokens: list = tokens.as_list()
1086
+ for ind_name in list_tokens:
1087
+ DLParser.kb.milp.show_vars.add_individual_to_show(ind_name)
1088
+ return tokens
1089
+
1090
+ @staticmethod
1091
+ # @pp.trace_parse_action
1092
+ def _show_instances(tokens: pp.ParseResults) -> pp.ParseResults:
1093
+
1094
+ if ConfigReader.DEBUG_PRINT:
1095
+ Util.debug(f"\t\t_show_instances -> {tokens}")
1096
+ list_tokens: list = tokens.as_list()
1097
+ for concept in list_tokens:
1098
+ concept: Concept = DLParser._to_concept(concept)
1099
+ DLParser.kb.milp.show_vars.add_concept_to_show(str(concept))
1100
+ return tokens
1101
+
1102
+ @staticmethod
1103
+ # @pp.trace_parse_action
1104
+ def _show_variables(tokens: pp.ParseResults) -> pp.ParseResults:
1105
+
1106
+ if ConfigReader.DEBUG_PRINT:
1107
+ Util.debug(f"\t\t_show_variables -> {tokens}")
1108
+ list_tokens: list = tokens.as_list()
1109
+ for variable_name in list_tokens:
1110
+ var: Variable = DLParser.kb.milp.get_variable(variable_name)
1111
+ DLParser.kb.milp.show_vars.add_variable(var, str(var))
1112
+ return tokens
1113
+
1114
+ @staticmethod
1115
+ # @pp.trace_parse_action
1116
+ def _show_languages(tokens: pp.ParseResults) -> pp.ParseResults:
1117
+
1118
+ if ConfigReader.DEBUG_PRINT:
1119
+ Util.debug(f"\t\t_show_languages -> {tokens}")
1120
+ DLParser.kb.show_language = True
1121
+ return tokens
1122
+
1123
+ @staticmethod
1124
+ # @pp.trace_parse_action
1125
+ def _parse_crisp_declarations(tokens: pp.ParseResults) -> pp.ParseResults:
1126
+
1127
+ if ConfigReader.DEBUG_PRINT:
1128
+ Util.debug(f"\t\t_parse_crisp_declarations -> {tokens}")
1129
+ list_tokens: list = tokens.as_list()
1130
+ if list_tokens[0] == FuzzyDLKeyword.CRISP_CONCEPT:
1131
+ for concept in list_tokens[1:]:
1132
+ concept: Concept = DLParser._to_concept(concept)
1133
+ DLParser.kb.set_crisp_concept(concept)
1134
+ elif list_tokens[0] == FuzzyDLKeyword.CRISP_ROLE:
1135
+ for role in list_tokens[1:]:
1136
+ DLParser.kb.set_crisp_role(role)
1137
+ return tokens
1138
+
1139
+ @staticmethod
1140
+ # @pp.trace_parse_action
1141
+ def _parse_fuzzy_similarity(tokens: pp.ParseResults) -> pp.ParseResults:
1142
+
1143
+ if ConfigReader.DEBUG_PRINT:
1144
+ Util.debug(f"\t\t_parse_fuzzy_similarity -> {tokens}")
1145
+ list_tokens: list = tokens.as_list()
1146
+ DLParser.kb.add_similarity_relation(list_tokens[0])
1147
+ return tokens
1148
+
1149
+ @staticmethod
1150
+ # @pp.trace_parse_action
1151
+ def _parse_fuzzy_equivalence(tokens: pp.ParseResults) -> pp.ParseResults:
1152
+
1153
+ if ConfigReader.DEBUG_PRINT:
1154
+ Util.debug(f"\t\t_parse_fuzzy_equivalence -> {tokens}")
1155
+ list_tokens: list = tokens.as_list()
1156
+ DLParser.kb.add_equivalence_relation(list_tokens[0])
1157
+ return tokens
1158
+
1159
+ @staticmethod
1160
+ # @pp.trace_parse_action
1161
+ def _parse_degree(tokens: pp.ParseResults) -> pp.ParseResults:
1162
+
1163
+ if ConfigReader.DEBUG_PRINT:
1164
+ Util.debug(f"\t\t_parse_degree -> {tokens}")
1165
+
1166
+ list_tokens: list = tokens.as_list()
1167
+ if isinstance(list_tokens[0], (int, float)):
1168
+ return pp.ParseResults([DegreeNumeric.get_degree(float(list_tokens[0]))])
1169
+ elif isinstance(list_tokens[0], Expression):
1170
+ return pp.ParseResults([DegreeExpression.get_degree(list_tokens[0])])
1171
+ elif isinstance(list_tokens[0], str):
1172
+ tc: typing.Optional[float] = DLParser.kb.get_truth_constants(list_tokens[0])
1173
+ if tc is not None:
1174
+ return pp.ParseResults([DegreeNumeric.get_degree(float(tc))])
1175
+ else:
1176
+ return pp.ParseResults(
1177
+ [
1178
+ DegreeVariable.get_degree(
1179
+ DLParser.kb.milp.get_variable(list_tokens[0])
1180
+ )
1181
+ ]
1182
+ )
1183
+ return tokens
1184
+
1185
+ @staticmethod
1186
+ # @pp.trace_parse_action
1187
+ def _parse_axioms(tokens: pp.ParseResults) -> pp.ParseResults:
1188
+
1189
+ if ConfigReader.DEBUG_PRINT:
1190
+ Util.debug(f"\t\t_parse_axioms -> {tokens}")
1191
+
1192
+ list_tokens: list = tokens.as_list()[0]
1193
+ if list_tokens[0] == FuzzyDLKeyword.INSTANCE:
1194
+ a: Individual = DLParser.kb.get_individual(list_tokens[1])
1195
+ c: Concept = DLParser._to_concept(list_tokens[2])
1196
+ d: Degree = (
1197
+ list_tokens[3]
1198
+ if len(list_tokens) > 3
1199
+ else DegreeNumeric.get_degree(1.0)
1200
+ )
1201
+ DLParser.kb.add_assertion(a, c, d)
1202
+ elif list_tokens[0] == FuzzyDLKeyword.RELATED:
1203
+ a: Individual = DLParser.kb.get_individual(list_tokens[1])
1204
+ b: Individual = DLParser.kb.get_individual(list_tokens[2])
1205
+ role: str = list_tokens[3]
1206
+ d: Degree = (
1207
+ list_tokens[4]
1208
+ if len(list_tokens) > 4
1209
+ else DegreeNumeric.get_degree(1.0)
1210
+ )
1211
+ if role in DLParser.kb.concrete_roles:
1212
+ Util.error(f"Error: Role {role} cannot be concrete and abstract.")
1213
+ DLParser.kb.add_relation(a, role, b, d)
1214
+ elif list_tokens[0] in (
1215
+ FuzzyDLKeyword.GOEDEL_IMPLIES,
1216
+ FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
1217
+ FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
1218
+ FuzzyDLKeyword.ZADEH_IMPLIES,
1219
+ FuzzyDLKeyword.IMPLIES,
1220
+ ):
1221
+ c1: Concept = DLParser._to_concept(list_tokens[1])
1222
+ c2: Concept = DLParser._to_concept(list_tokens[2])
1223
+ d: Degree = (
1224
+ list_tokens[3]
1225
+ if len(list_tokens) > 3
1226
+ else DegreeNumeric.get_degree(1.0)
999
1227
  )
1000
- return tokens
1228
+ if list_tokens[0] == FuzzyDLKeyword.IMPLIES:
1229
+ DLParser.kb.implies(c1, c2, d)
1230
+ elif list_tokens[0] == FuzzyDLKeyword.GOEDEL_IMPLIES:
1231
+ DLParser.kb.goedel_implies(c1, c2, d)
1232
+ elif list_tokens[0] == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
1233
+ DLParser.kb.lukasiewicz_implies(c1, c2, d)
1234
+ elif list_tokens[0] == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
1235
+ DLParser.kb.kleene_dienes_implies(c1, c2, d)
1236
+ elif list_tokens[0] == FuzzyDLKeyword.ZADEH_IMPLIES:
1237
+ DLParser.kb.zadeh_implies(c1, c2)
1238
+ elif list_tokens[0] == FuzzyDLKeyword.ZADEH_IMPLIES:
1239
+ c1: Concept = DLParser._to_concept(list_tokens[1])
1240
+ c2: Concept = DLParser._to_concept(list_tokens[2])
1241
+ DLParser.kb.zadeh_implies(c1, c2)
1242
+ elif list_tokens[0] == FuzzyDLKeyword.DEFINE_CONCEPT:
1243
+ name: str = list_tokens[1]
1244
+ c: Concept = DLParser._to_concept(list_tokens[2])
1245
+ DLParser.kb.define_concept(name, c)
1246
+ elif list_tokens[0] == FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT:
1247
+ name: str = list_tokens[1]
1248
+ c: Concept = DLParser._to_concept(list_tokens[2])
1249
+ DLParser.kb.define_atomic_concept(name, c, LogicOperatorType.ZADEH, 1.0)
1250
+ elif list_tokens[0] == FuzzyDLKeyword.EQUIVALENT_CONCEPTS:
1251
+ c1: Concept = DLParser._to_concept(list_tokens[1])
1252
+ c2: Concept = DLParser._to_concept(list_tokens[2])
1253
+ DLParser.kb.define_equivalent_concepts(c1, c2)
1254
+ elif list_tokens[0] == FuzzyDLKeyword.DISJOINT_UNION:
1255
+ concepts: list[str] = [
1256
+ str(DLParser._to_concept(t)) for t in list_tokens[1:]
1257
+ ]
1258
+ DLParser.kb.add_disjoint_union_concept(concepts)
1259
+ elif list_tokens[0] == FuzzyDLKeyword.DISJOINT:
1260
+ concepts: list[Concept] = [DLParser._to_concept(t) for t in list_tokens[1:]]
1261
+ DLParser.kb.add_concepts_disjoint(concepts)
1262
+ elif list_tokens[0] in (FuzzyDLKeyword.RANGE, FuzzyDLKeyword.DOMAIN):
1263
+ role: str = list_tokens[1]
1264
+ concept: Concept = DLParser._to_concept(list_tokens[2])
1265
+ if list_tokens[0] == FuzzyDLKeyword.RANGE:
1266
+ DLParser.kb.check_role(role, concept)
1267
+ DLParser.kb.role_range(role, concept)
1268
+ else:
1269
+ DLParser.kb.role_domain(role, concept)
1270
+ elif list_tokens[0] == FuzzyDLKeyword.FUNCTIONAL:
1271
+ role: str = list_tokens[1]
1272
+ DLParser.kb.role_is_functional(role)
1273
+ elif list_tokens[0] == FuzzyDLKeyword.TRANSITIVE:
1274
+ role: str = list_tokens[1]
1275
+ DLParser.kb.role_is_transitive(role)
1276
+ elif list_tokens[0] == FuzzyDLKeyword.SYMMETRIC:
1277
+ role: str = list_tokens[1]
1278
+ DLParser.kb.role_is_symmetric(role)
1279
+ elif list_tokens[0] == FuzzyDLKeyword.REFLEXIVE:
1280
+ role: str = list_tokens[1]
1281
+ DLParser.kb.role_is_reflexive(role)
1282
+ elif list_tokens[0] == FuzzyDLKeyword.INVERSE_FUNCTIONAL:
1283
+ role: str = list_tokens[1]
1284
+ if role in DLParser.kb.concrete_roles:
1285
+ Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
1286
+ DLParser.kb.role_is_inverse_functional(role)
1287
+ elif list_tokens[0] == FuzzyDLKeyword.INVERSE:
1288
+ role: str = list_tokens[1]
1289
+ inv_role: str = list_tokens[2]
1290
+ if role in DLParser.kb.concrete_roles:
1291
+ Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
1292
+ elif inv_role in DLParser.kb.concrete_roles:
1293
+ Util.error(
1294
+ f"Error: Concrete role {inv_role} cannot have an inverse role."
1295
+ )
1296
+ else:
1297
+ DLParser.kb.add_inverse_roles(role, inv_role)
1298
+ elif list_tokens[0] == FuzzyDLKeyword.IMPLIES_ROLE:
1299
+ role_c: str = list_tokens[1]
1300
+ role_p: str = list_tokens[2]
1301
+ d: float = list_tokens[3] if len(list_tokens) > 3 else 1.0
1302
+ DLParser.kb.role_implies(role_c, role_p, d)
1303
+ return tokens
1001
1304
 
1305
+ @staticmethod
1306
+ # @pp.trace_parse_action
1307
+ def _parse_queries(tokens: pp.ParseResults) -> pp.ParseResults:
1002
1308
 
1003
- def _parse_axioms(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
1004
- if ConfigReader.DEBUG_PRINT:
1005
- Util.debug(f"\t\t_parse_axioms -> {tokens}")
1309
+ if ConfigReader.DEBUG_PRINT:
1310
+ Util.debug(f"\t\t_parse_queries -> {tokens}")
1006
1311
 
1007
- list_tokens: list = tokens.as_list()[0]
1008
- if list_tokens[0] == FuzzyDLKeyword.INSTANCE:
1009
- a: Individual = kb.get_individual(list_tokens[1])
1010
- c: Concept = _to_concept(kb, list_tokens[2])
1011
- d: Degree = (
1012
- list_tokens[3] if len(list_tokens) > 3 else DegreeNumeric.get_degree(1.0)
1013
- )
1014
- kb.add_assertion(a, c, d)
1015
- elif list_tokens[0] == FuzzyDLKeyword.RELATED:
1016
- a: Individual = kb.get_individual(list_tokens[1])
1017
- b: Individual = kb.get_individual(list_tokens[2])
1018
- role: str = list_tokens[3]
1019
- d: Degree = (
1020
- list_tokens[4] if len(list_tokens) > 4 else DegreeNumeric.get_degree(1.0)
1021
- )
1022
- if role in kb.concrete_roles:
1023
- Util.error(f"Error: Role {role} cannot be concrete and abstract.")
1024
- kb.add_relation(a, role, b, d)
1025
- elif list_tokens[0] in (
1026
- FuzzyDLKeyword.GOEDEL_IMPLIES,
1027
- FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
1028
- FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
1029
- FuzzyDLKeyword.IMPLIES,
1030
- ):
1031
- c1: Concept = _to_concept(kb, list_tokens[1])
1032
- c2: Concept = _to_concept(kb, list_tokens[2])
1033
- d: Degree = (
1034
- list_tokens[3] if len(list_tokens) > 3 else DegreeNumeric.get_degree(1.0)
1035
- )
1036
- if list_tokens[0] == FuzzyDLKeyword.IMPLIES:
1037
- kb.implies(c1, c2, d)
1038
- elif list_tokens[0] == FuzzyDLKeyword.GOEDEL_IMPLIES:
1039
- kb.goedel_implies(c1, c2, d)
1040
- elif list_tokens[0] == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
1041
- kb.lukasiewicz_implies(c1, c2, d)
1042
- elif list_tokens[0] == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
1043
- kb.kleene_dienes_implies(c1, c2, d)
1044
- elif list_tokens[0] == FuzzyDLKeyword.ZADEH_IMPLIES:
1045
- c1: Concept = _to_concept(kb, list_tokens[1])
1046
- c2: Concept = _to_concept(kb, list_tokens[2])
1047
- kb.zadeh_implies(c1, c2)
1048
- elif list_tokens[0] == FuzzyDLKeyword.DEFINE_CONCEPT:
1049
- name: str = list_tokens[1]
1050
- c: Concept = _to_concept(kb, list_tokens[2])
1051
- kb.define_concept(name, c)
1052
- elif list_tokens[0] == FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT:
1053
- name: str = list_tokens[1]
1054
- c: Concept = _to_concept(kb, list_tokens[2])
1055
- kb.define_atomic_concept(name, c, LogicOperatorType.ZADEH, 1.0)
1056
- elif list_tokens[0] == FuzzyDLKeyword.EQUIVALENT_CONCEPTS:
1057
- c1: Concept = _to_concept(kb, list_tokens[1])
1058
- c2: Concept = _to_concept(kb, list_tokens[2])
1059
- kb.define_equivalent_concepts(c1, c2)
1060
- elif list_tokens[0] == FuzzyDLKeyword.DISJOINT_UNION:
1061
- concepts: list[str] = [str(_to_concept(kb, t)) for t in list_tokens[1:]]
1062
- kb.add_disjoint_union_concept(concepts)
1063
- elif list_tokens[0] == FuzzyDLKeyword.DISJOINT:
1064
- concepts: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
1065
- kb.add_concepts_disjoint(concepts)
1066
- elif list_tokens[0] in (FuzzyDLKeyword.RANGE, FuzzyDLKeyword.DOMAIN):
1067
- role: str = list_tokens[1]
1068
- concept: Concept = _to_concept(kb, list_tokens[2])
1069
- if list_tokens[0] == FuzzyDLKeyword.RANGE:
1070
- kb.check_role(role, concept)
1071
- kb.role_range(role, concept)
1072
- else:
1073
- kb.role_domain(role, concept)
1074
- elif list_tokens[0] == FuzzyDLKeyword.FUNCTIONAL:
1075
- role: str = list_tokens[1]
1076
- kb.role_is_functional(role)
1077
- elif list_tokens[0] == FuzzyDLKeyword.TRANSITIVE:
1078
- role: str = list_tokens[1]
1079
- kb.role_is_transitive(role)
1080
- elif list_tokens[0] == FuzzyDLKeyword.SYMMETRIC:
1081
- role: str = list_tokens[1]
1082
- kb.role_is_symmetric(role)
1083
- elif list_tokens[0] == FuzzyDLKeyword.REFLEXIVE:
1084
- role: str = list_tokens[1]
1085
- kb.role_is_reflexive(role)
1086
- elif list_tokens[0] == FuzzyDLKeyword.INVERSE_FUNCTIONAL:
1087
- role: str = list_tokens[1]
1088
- if role in kb.concrete_roles:
1089
- Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
1090
- kb.role_is_inverse_functional(role)
1091
- elif list_tokens[0] == FuzzyDLKeyword.INVERSE:
1092
- role: str = list_tokens[1]
1093
- inv_role: str = list_tokens[2]
1094
- if role in kb.concrete_roles:
1095
- Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
1096
- elif inv_role in kb.concrete_roles:
1097
- Util.error(f"Error: Concrete role {inv_role} cannot have an inverse role.")
1098
- else:
1099
- kb.add_inverse_roles(role, inv_role)
1100
- elif list_tokens[0] == FuzzyDLKeyword.IMPLIES_ROLE:
1101
- role_c: str = list_tokens[1]
1102
- role_p: str = list_tokens[2]
1103
- d: float = list_tokens[3] if len(list_tokens) > 3 else 1.0
1104
- kb.role_implies(role_c, role_p, d)
1105
- return tokens
1106
-
1107
-
1108
- def _parse_queries(
1109
- kb: KnowledgeBase, queries_list: list[Query], tokens: pp.ParseResults
1110
- ) -> pp.ParseResults:
1111
- if ConfigReader.DEBUG_PRINT:
1112
- Util.debug(f"\t\t_parse_queries -> {tokens}")
1113
-
1114
- list_tokens: list[str] = tokens.as_list()[0]
1115
-
1116
- if list_tokens[0] == FuzzyDLKeyword.ALL_INSTANCES_QUERY:
1117
- queries_list.append(AllInstancesQuery(list_tokens[1]))
1118
- elif list_tokens[0] == FuzzyDLKeyword.SAT_QUERY:
1119
- queries_list.append(KbSatisfiableQuery())
1120
- elif list_tokens[0] in (FuzzyDLKeyword.MIN_SAT_QUERY, FuzzyDLKeyword.MAX_SAT_QUERY):
1121
- _class: Query = (
1122
- MinSatisfiableQuery
1123
- if list_tokens[0] == FuzzyDLKeyword.MIN_SAT_QUERY
1124
- else MaxSatisfiableQuery
1125
- )
1126
- c: Concept = _to_concept(kb, list_tokens[1])
1127
- if len(list_tokens) > 2:
1128
- queries_list.append(_class(c, kb.get_individual(list_tokens[2])))
1129
- else:
1130
- queries_list.append(_class(c))
1131
- elif list_tokens[0] in (
1132
- FuzzyDLKeyword.MAX_INSTANCE_QUERY,
1133
- FuzzyDLKeyword.MIN_INSTANCE_QUERY,
1134
- ):
1135
- _class: Query = (
1136
- MaxInstanceQuery
1137
- if list_tokens[0] == FuzzyDLKeyword.MAX_INSTANCE_QUERY
1138
- else MinInstanceQuery
1139
- )
1140
- a: Individual = kb.get_individual(list_tokens[1])
1141
- c: Concept = _to_concept(kb, list_tokens[2])
1142
- queries_list.append(_class(c, a))
1143
- elif list_tokens[0] in (
1144
- FuzzyDLKeyword.MAX_SUBS_QUERY,
1145
- FuzzyDLKeyword.MIN_SUBS_QUERY,
1146
- FuzzyDLKeyword.MAX_G_SUBS_QUERY,
1147
- FuzzyDLKeyword.MIN_G_SUBS_QUERY,
1148
- FuzzyDLKeyword.MAX_L_SUBS_QUERY,
1149
- FuzzyDLKeyword.MIN_L_SUBS_QUERY,
1150
- FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
1151
- FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
1152
- ):
1153
- _class = (
1154
- MaxSubsumesQuery
1155
- if list_tokens[0].lower().startswith("max")
1156
- else MinSubsumesQuery
1157
- )
1158
- c1: Concept = _to_concept(kb, list_tokens[1])
1159
- c2: Concept = _to_concept(kb, list_tokens[2])
1160
- if list_tokens[0] in (
1161
- FuzzyDLKeyword.MAX_SUBS_QUERY,
1162
- FuzzyDLKeyword.MIN_SUBS_QUERY,
1312
+ list_tokens: list[str] = tokens.as_list()[0]
1313
+
1314
+ if list_tokens[0] == FuzzyDLKeyword.ALL_INSTANCES_QUERY:
1315
+ DLParser.queries_list.append(AllInstancesQuery(list_tokens[1]))
1316
+ elif list_tokens[0] == FuzzyDLKeyword.SAT_QUERY:
1317
+ DLParser.queries_list.append(KbSatisfiableQuery())
1318
+ elif list_tokens[0] in (
1319
+ FuzzyDLKeyword.MIN_SAT_QUERY,
1320
+ FuzzyDLKeyword.MAX_SAT_QUERY,
1163
1321
  ):
1164
- if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
1165
- queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
1322
+ _class: Query = (
1323
+ MinSatisfiableQuery
1324
+ if list_tokens[0] == FuzzyDLKeyword.MIN_SAT_QUERY
1325
+ else MaxSatisfiableQuery
1326
+ )
1327
+ c: Concept = DLParser._to_concept(list_tokens[1])
1328
+ if len(list_tokens) > 2:
1329
+ DLParser.queries_list.append(
1330
+ _class(c, DLParser.kb.get_individual(list_tokens[2]))
1331
+ )
1166
1332
  else:
1167
- queries_list.append(_class(c1, c2, LogicOperatorType.ZADEH))
1333
+ DLParser.queries_list.append(_class(c))
1168
1334
  elif list_tokens[0] in (
1169
- FuzzyDLKeyword.MAX_G_SUBS_QUERY,
1170
- FuzzyDLKeyword.MIN_G_SUBS_QUERY,
1335
+ FuzzyDLKeyword.MAX_INSTANCE_QUERY,
1336
+ FuzzyDLKeyword.MIN_INSTANCE_QUERY,
1171
1337
  ):
1172
- queries_list.append(_class(c1, c2, LogicOperatorType.GOEDEL))
1338
+ _class: Query = (
1339
+ MaxInstanceQuery
1340
+ if list_tokens[0] == FuzzyDLKeyword.MAX_INSTANCE_QUERY
1341
+ else MinInstanceQuery
1342
+ )
1343
+ a: Individual = DLParser.kb.get_individual(list_tokens[1])
1344
+ c: Concept = DLParser._to_concept(list_tokens[2])
1345
+ DLParser.queries_list.append(_class(c, a))
1173
1346
  elif list_tokens[0] in (
1347
+ FuzzyDLKeyword.MAX_SUBS_QUERY,
1348
+ FuzzyDLKeyword.MIN_SUBS_QUERY,
1349
+ FuzzyDLKeyword.MAX_G_SUBS_QUERY,
1350
+ FuzzyDLKeyword.MIN_G_SUBS_QUERY,
1174
1351
  FuzzyDLKeyword.MAX_L_SUBS_QUERY,
1175
1352
  FuzzyDLKeyword.MIN_L_SUBS_QUERY,
1176
- ):
1177
- queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
1178
- elif list_tokens[0] in (
1179
1353
  FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
1180
1354
  FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
1181
1355
  ):
1182
- queries_list.append(_class(c1, c2, LogicOperatorType.KLEENE_DIENES))
1183
- elif list_tokens[0] in (
1184
- FuzzyDLKeyword.MAX_RELATED_QUERY,
1185
- FuzzyDLKeyword.MIN_RELATED_QUERY,
1186
- ):
1187
- a: Individual = kb.get_individual(list_tokens[1])
1188
- b: Individual = kb.get_individual(list_tokens[2])
1189
- role: str = list_tokens[3]
1190
- if role in kb.concrete_roles:
1191
- Util.error(f"Error: Role {role} cannot be concrete and abstract.")
1192
- kb.abstract_roles.add(role)
1193
- if list_tokens[0] == FuzzyDLKeyword.MAX_RELATED_QUERY:
1194
- queries_list.append(MaxRelatedQuery(a, b, role))
1195
- else:
1196
- queries_list.append(MinRelatedQuery(a, b, role))
1197
- elif list_tokens[0] == FuzzyDLKeyword.MAX_VAR_QUERY:
1198
- queries_list.append(MaxQuery(list_tokens[1]))
1199
- elif list_tokens[0] == FuzzyDLKeyword.MIN_VAR_QUERY:
1200
- queries_list.append(MinQuery(list_tokens[1]))
1201
- elif list_tokens[0] in (
1202
- FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY,
1203
- FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY,
1204
- FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY,
1205
- ):
1206
- c: Concept = _to_concept(kb, list_tokens[1])
1207
- a: Individual = kb.get_individual(list_tokens[2])
1208
- role: str = list_tokens[3]
1209
- if kb.concrete_features.get(role) is None:
1210
- Util.error(f"Error: Feature {role} has not been defined.")
1211
- if list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY:
1212
- queries_list.append(LomDefuzzifyQuery(c, a, role))
1213
- elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY:
1214
- queries_list.append(SomDefuzzifyQuery(c, a, role))
1215
- elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY:
1216
- queries_list.append(MomDefuzzifyQuery(c, a, role))
1217
- elif list_tokens[0] == FuzzyDLKeyword.BNP_QUERY:
1218
- if not TriangularFuzzyNumber.has_defined_range():
1219
- Util.error(
1220
- "Error: The range of the fuzzy numbers has to be defined before being used."
1356
+ _class = (
1357
+ MaxSubsumesQuery
1358
+ if list_tokens[0].lower().startswith("max")
1359
+ else MinSubsumesQuery
1221
1360
  )
1222
- queries_list.append(BnpQuery(list_tokens[1]))
1223
- return tokens
1224
-
1225
-
1226
- class DLParser(object):
1361
+ c1: Concept = DLParser._to_concept(list_tokens[1])
1362
+ c2: Concept = DLParser._to_concept(list_tokens[2])
1363
+ if list_tokens[0] in (
1364
+ FuzzyDLKeyword.MAX_SUBS_QUERY,
1365
+ FuzzyDLKeyword.MIN_SUBS_QUERY,
1366
+ ):
1367
+ if DLParser.kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
1368
+ DLParser.queries_list.append(
1369
+ _class(c1, c2, LogicOperatorType.LUKASIEWICZ)
1370
+ )
1371
+ else:
1372
+ DLParser.queries_list.append(
1373
+ _class(c1, c2, LogicOperatorType.ZADEH)
1374
+ )
1375
+ elif list_tokens[0] in (
1376
+ FuzzyDLKeyword.MAX_G_SUBS_QUERY,
1377
+ FuzzyDLKeyword.MIN_G_SUBS_QUERY,
1378
+ ):
1379
+ DLParser.queries_list.append(_class(c1, c2, LogicOperatorType.GOEDEL))
1380
+ elif list_tokens[0] in (
1381
+ FuzzyDLKeyword.MAX_L_SUBS_QUERY,
1382
+ FuzzyDLKeyword.MIN_L_SUBS_QUERY,
1383
+ ):
1384
+ DLParser.queries_list.append(
1385
+ _class(c1, c2, LogicOperatorType.LUKASIEWICZ)
1386
+ )
1387
+ elif list_tokens[0] in (
1388
+ FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
1389
+ FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
1390
+ ):
1391
+ DLParser.queries_list.append(
1392
+ _class(c1, c2, LogicOperatorType.KLEENE_DIENES)
1393
+ )
1394
+ elif list_tokens[0] in (
1395
+ FuzzyDLKeyword.MAX_RELATED_QUERY,
1396
+ FuzzyDLKeyword.MIN_RELATED_QUERY,
1397
+ ):
1398
+ a: Individual = DLParser.kb.get_individual(list_tokens[1])
1399
+ b: Individual = DLParser.kb.get_individual(list_tokens[2])
1400
+ role: str = list_tokens[3]
1401
+ if role in DLParser.kb.concrete_roles:
1402
+ Util.error(f"Error: Role {role} cannot be concrete and abstract.")
1403
+ DLParser.kb.abstract_roles.add(role)
1404
+ if list_tokens[0] == FuzzyDLKeyword.MAX_RELATED_QUERY:
1405
+ DLParser.queries_list.append(MaxRelatedQuery(a, b, role))
1406
+ else:
1407
+ DLParser.queries_list.append(MinRelatedQuery(a, b, role))
1408
+ elif list_tokens[0] == FuzzyDLKeyword.MAX_VAR_QUERY:
1409
+ DLParser.queries_list.append(MaxQuery(list_tokens[1]))
1410
+ elif list_tokens[0] == FuzzyDLKeyword.MIN_VAR_QUERY:
1411
+ DLParser.queries_list.append(MinQuery(list_tokens[1]))
1412
+ elif list_tokens[0] in (
1413
+ FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY,
1414
+ FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY,
1415
+ FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY,
1416
+ ):
1417
+ c: Concept = DLParser._to_concept(list_tokens[1])
1418
+ a: Individual = DLParser.kb.get_individual(list_tokens[2])
1419
+ role: str = list_tokens[3]
1420
+ if DLParser.kb.concrete_features.get(role) is None:
1421
+ Util.error(f"Error: Feature {role} has not been defined.")
1422
+ if list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY:
1423
+ DLParser.queries_list.append(LomDefuzzifyQuery(c, a, role))
1424
+ elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY:
1425
+ DLParser.queries_list.append(SomDefuzzifyQuery(c, a, role))
1426
+ elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY:
1427
+ DLParser.queries_list.append(MomDefuzzifyQuery(c, a, role))
1428
+ elif list_tokens[0] == FuzzyDLKeyword.BNP_QUERY:
1429
+ if not TriangularFuzzyNumber.has_defined_range():
1430
+ Util.error(
1431
+ "Error: The range of the fuzzy numbers has to be defined before being used."
1432
+ )
1433
+ DLParser.queries_list.append(
1434
+ BnpQuery(
1435
+ list_tokens[1]
1436
+ if isinstance(list_tokens[1], TriangularFuzzyNumber)
1437
+ else DLParser.kb.fuzzy_numbers.get(list_tokens[1])
1438
+ )
1439
+ )
1440
+ return tokens
1227
1441
 
1228
1442
  @staticmethod
1229
- def get_grammatics(
1230
- kb: KnowledgeBase, queries_list: list[Query]
1231
- ) -> pp.ParserElement:
1443
+ def get_grammatics() -> pp.ParserElement:
1232
1444
  """
1233
1445
  This function generate the grammatics to parse the predicate wih formula "formula".
1234
1446
 
@@ -1253,7 +1465,7 @@ class DLParser(object):
1253
1465
  numbers = (
1254
1466
  pp.Combine(pp.Opt(pp.one_of(["+", "-"])) + digits + pp.Opt("." + digits))
1255
1467
  .set_results_name("number", list_all_matches=True)
1256
- .set_parse_action(_to_number)
1468
+ .set_parse_action(DLParser._to_number)
1257
1469
  )
1258
1470
 
1259
1471
  simple_string = pp.Word(pp.alphas + "_", pp.alphanums + "_'").set_results_name(
@@ -1280,7 +1492,7 @@ class DLParser(object):
1280
1492
  + rbrace
1281
1493
  )
1282
1494
  .set_results_name("fuzzy_logics", list_all_matches=True)
1283
- .add_parse_action(partial(_fuzzy_logic_parser, kb))
1495
+ .add_parse_action(DLParser._fuzzy_logic_parser)
1284
1496
  )
1285
1497
 
1286
1498
  comment_line = (comment + any_not_newline).set_results_name(
@@ -1292,13 +1504,19 @@ class DLParser(object):
1292
1504
  weighted_concept_part = (
1293
1505
  (lbrace + numbers + concept + rbrace)
1294
1506
  .set_results_name("simple_weighted_concepts_single", list_all_matches=True)
1295
- .set_parse_action(partial(_parse_weighted_concept_simple, kb))
1507
+ .set_parse_action(DLParser._parse_weighted_concept_simple)
1296
1508
  )
1297
1509
 
1298
1510
  simple_fuzzy_number = (
1299
- (variables | lbrace + numbers[3] + rbrace | numbers)
1511
+ (
1512
+ variables
1513
+ | lbrace
1514
+ + (numbers[3] | pp.DelimitedList(numbers, min=3, max=3))
1515
+ + rbrace
1516
+ | numbers
1517
+ )
1300
1518
  .set_results_name("simple_fuzzy_numbers", list_all_matches=True)
1301
- .set_parse_action(partial(_create_fuzzy_number, kb))
1519
+ .set_parse_action(DLParser._create_fuzzy_number)
1302
1520
  )
1303
1521
 
1304
1522
  fuzzy_number_expr = pp.Forward()
@@ -1311,7 +1529,7 @@ class DLParser(object):
1311
1529
  FuzzyDLKeyword.FEATURE_MUL.get_name(),
1312
1530
  ]
1313
1531
  )
1314
- + pp.OneOrMore(fuzzy_number_expr)
1532
+ + fuzzy_number_expr[1, ...]
1315
1533
  + rbrace
1316
1534
  | lbrace
1317
1535
  + pp.one_of(
@@ -1333,19 +1551,53 @@ class DLParser(object):
1333
1551
  + rbrace
1334
1552
  )
1335
1553
  .set_results_name("fuzzy_numbers", list_all_matches=True)
1336
- .set_parse_action(partial(_set_fuzzy_number, kb))
1554
+ .set_parse_action(DLParser._set_fuzzy_number)
1337
1555
  )
1338
1556
 
1339
- datatype_restriction_function = (
1557
+ datatype_restriction_operand = pp.Forward()
1558
+ datatype_restriction_function = pp.Forward()
1559
+
1560
+ datatype_restriction_mul_expressions = pp.Group(
1340
1561
  (
1341
- variables
1562
+ lbrace
1563
+ + numbers
1564
+ + pp.Opt(FuzzyDLKeyword.MUL.get_value()).suppress()
1565
+ + datatype_restriction_function
1566
+ + rbrace
1567
+ )
1568
+ .set_results_name("restrictions", list_all_matches=True)
1569
+ .set_parse_action(DLParser._parse_restrictions)
1570
+ )
1571
+ datatype_restriction_sub_expressions = pp.Group(
1572
+ (
1573
+ lbrace
1574
+ + datatype_restriction_function
1575
+ + FuzzyDLKeyword.SUB.get_value()
1576
+ + datatype_restriction_function
1577
+ + rbrace
1578
+ )
1579
+ .set_results_name("restrictions", list_all_matches=True)
1580
+ .set_parse_action(DLParser._parse_restrictions)
1581
+ )
1582
+ datatype_restriction_operand <<= (
1583
+ (
1584
+ datatype_restriction_mul_expressions
1585
+ | datatype_restriction_sub_expressions
1586
+ | variables
1342
1587
  | numbers
1343
- | numbers + pp.Opt(FuzzyDLKeyword.MUL.get_value()) + variables
1344
- | variables + FuzzyDLKeyword.SUB.get_value() + variables
1345
- | pp.DelimitedList(variables, delim=FuzzyDLKeyword.SUM.get_name())
1346
1588
  )
1347
1589
  .set_results_name("restrictions", list_all_matches=True)
1348
- .set_parse_action(partial(_parse_restrictions, kb))
1590
+ .set_parse_action(DLParser._parse_restrictions)
1591
+ )
1592
+ datatype_restriction_function <<= (
1593
+ pp.infix_notation(
1594
+ datatype_restriction_operand,
1595
+ [
1596
+ (FuzzyDLKeyword.SUM.get_value(), 2, pp.OpAssoc.LEFT),
1597
+ ],
1598
+ )
1599
+ .set_results_name("restrictions", list_all_matches=True)
1600
+ .set_parse_action(DLParser._parse_restrictions)
1349
1601
  )
1350
1602
 
1351
1603
  datatype_restrictions = (
@@ -1363,7 +1615,7 @@ class DLParser(object):
1363
1615
  + rbrace
1364
1616
  )
1365
1617
  .set_results_name("datatype_restrictions", list_all_matches=True)
1366
- .set_parse_action(partial(_parse_datatype_restriction, kb))
1618
+ .set_parse_action(DLParser._parse_datatype_restriction)
1367
1619
  )
1368
1620
 
1369
1621
  concept <<= (
@@ -1373,7 +1625,7 @@ class DLParser(object):
1373
1625
  | FuzzyDLKeyword.BOTTOM.get_value()
1374
1626
  )
1375
1627
  .set_results_name("truth_constants", list_all_matches=True)
1376
- .set_parse_action(partial(_to_top_bottom_concept, kb))
1628
+ .set_parse_action(DLParser._to_top_bottom_concept)
1377
1629
  | datatype_restrictions.set_results_name(
1378
1630
  "restriction_concepts", list_all_matches=True
1379
1631
  )
@@ -1384,30 +1636,32 @@ class DLParser(object):
1384
1636
  + (
1385
1637
  (
1386
1638
  (
1387
- pp.one_of(
1639
+ pp.Literal("[").suppress()
1640
+ + pp.one_of(
1388
1641
  [
1389
1642
  FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
1390
1643
  FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
1391
1644
  ]
1392
1645
  )
1393
1646
  + (variables | numbers)
1647
+ + pp.Literal("]").suppress()
1394
1648
  + concept
1395
1649
  )
1396
1650
  .set_results_name("threshold_concepts", list_all_matches=True)
1397
- .set_parse_action(partial(_parse_threshold_concept, kb))
1651
+ .set_parse_action(DLParser._parse_threshold_concept)
1398
1652
  | (
1399
1653
  pp.one_of(
1400
1654
  [
1401
- FuzzyDLKeyword.AND.get_name(),
1402
1655
  FuzzyDLKeyword.GOEDEL_AND.get_name(),
1403
1656
  FuzzyDLKeyword.LUKASIEWICZ_AND.get_name(),
1404
- FuzzyDLKeyword.OR.get_name(),
1657
+ FuzzyDLKeyword.AND.get_name(),
1405
1658
  FuzzyDLKeyword.GOEDEL_OR.get_name(),
1406
1659
  FuzzyDLKeyword.LUKASIEWICZ_OR.get_name(),
1407
- FuzzyDLKeyword.IMPLIES.get_name(),
1660
+ FuzzyDLKeyword.OR.get_name(),
1408
1661
  FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
1409
1662
  FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
1410
1663
  FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
1664
+ FuzzyDLKeyword.IMPLIES.get_name(),
1411
1665
  ]
1412
1666
  )
1413
1667
  + concept[2, ...]
@@ -1418,7 +1672,7 @@ class DLParser(object):
1418
1672
  + (variables | concept)
1419
1673
  ).set_results_name("some_concepts", list_all_matches=True)
1420
1674
  | (
1421
- FuzzyDLKeyword.HAS_VALUE.get_value() + variables + variables
1675
+ FuzzyDLKeyword.HAS_VALUE.get_value() + variables[2]
1422
1676
  ).set_results_name("has_value_concepts", list_all_matches=True)
1423
1677
  | pp.one_of(
1424
1678
  [
@@ -1435,16 +1689,16 @@ class DLParser(object):
1435
1689
  + concept
1436
1690
  )
1437
1691
  .set_results_name("binary_concepts", list_all_matches=True)
1438
- .set_parse_action(partial(_parse_binary_concept, kb))
1692
+ .set_parse_action(DLParser._parse_binary_concept)
1439
1693
  | (
1440
1694
  FuzzyDLKeyword.NOT.get_value() + concept
1441
1695
  | FuzzyDLKeyword.SELF.get_value() + variables
1442
1696
  )
1443
1697
  .set_results_name("unary_concepts", list_all_matches=True)
1444
- .set_parse_action(partial(_parse_unary_concept, kb))
1698
+ .set_parse_action(DLParser._parse_unary_concept)
1445
1699
  | (variables + concept)
1446
1700
  .set_results_name("modifier_concepts", list_all_matches=True)
1447
- .set_parse_action(partial(_parse_modifier_concept, kb))
1701
+ .set_parse_action(DLParser._parse_modifier_concept)
1448
1702
  | (
1449
1703
  pp.one_of(
1450
1704
  [
@@ -1457,14 +1711,14 @@ class DLParser(object):
1457
1711
  + pp.OneOrMore(weighted_concept_part)
1458
1712
  )
1459
1713
  .set_results_name("weighted_concepts", list_all_matches=True)
1460
- .set_parse_action(partial(_parse_weighted_concept, kb))
1714
+ .set_parse_action(DLParser._parse_weighted_concept)
1461
1715
  | (
1462
1716
  FuzzyDLKeyword.Q_OWA.get_value().suppress()
1463
1717
  + variables
1464
- + pp.OneOrMore(concept)
1718
+ + concept[1, ...]
1465
1719
  )
1466
1720
  .set_results_name("q_owas", list_all_matches=True)
1467
- .set_parse_action(partial(_parse_q_owa_concept, kb))
1721
+ .set_parse_action(DLParser._parse_q_owa_concept)
1468
1722
  | (
1469
1723
  pp.one_of(
1470
1724
  [
@@ -1475,14 +1729,14 @@ class DLParser(object):
1475
1729
  ]
1476
1730
  )
1477
1731
  + lbrace
1478
- + pp.OneOrMore(numbers)
1732
+ + numbers[1, ...]
1479
1733
  + rbrace
1480
1734
  + lbrace
1481
- + pp.OneOrMore(concept)
1735
+ + concept[1, ...]
1482
1736
  + rbrace
1483
1737
  )
1484
1738
  .set_results_name("owa_integrals", list_all_matches=True)
1485
- .set_parse_action(partial(_parse_owa_integral_concept, kb))
1739
+ .set_parse_action(DLParser._parse_owa_integral_concept)
1486
1740
  )
1487
1741
  + rbrace
1488
1742
  )
@@ -1499,25 +1753,25 @@ class DLParser(object):
1499
1753
  + rbrace
1500
1754
  | FuzzyDLKeyword.TRIANGULAR_MODIFIER.get_value()
1501
1755
  + lbrace
1502
- + numbers[3]
1756
+ + (numbers[3] | pp.DelimitedList(numbers, min=3, max=3))
1503
1757
  + rbrace
1504
1758
  )
1505
1759
  + rbrace
1506
1760
  )
1507
1761
  .set_results_name("modifiers", list_all_matches=True)
1508
- .set_parse_action(partial(_parse_modifier, kb))
1762
+ .set_parse_action(DLParser._parse_modifier)
1509
1763
  )
1510
1764
 
1511
1765
  truth_constants = (
1512
1766
  (
1513
1767
  lbrace
1514
- + FuzzyDLKeyword.DEFINE_TRUTH_CONSTANT.get_value()
1768
+ + FuzzyDLKeyword.DEFINE_TRUTH_CONSTANT.get_value().suppress()
1515
1769
  + variables
1516
1770
  + numbers
1517
1771
  + rbrace
1518
1772
  )
1519
1773
  .set_results_name("truth_concepts", list_all_matches=True)
1520
- .set_parse_action(partial(_parse_truth_constants, kb))
1774
+ .set_parse_action(DLParser._parse_truth_constants)
1521
1775
  )
1522
1776
 
1523
1777
  fuzzy_concept = (
@@ -1558,7 +1812,7 @@ class DLParser(object):
1558
1812
  + rbrace
1559
1813
  )
1560
1814
  .set_results_name("fuzzy_concepts", list_all_matches=True)
1561
- .set_parse_action(partial(_parse_fuzzy_concept, kb))
1815
+ .set_parse_action(DLParser._parse_fuzzy_concept)
1562
1816
  )
1563
1817
 
1564
1818
  fuzzy_range = (
@@ -1569,7 +1823,7 @@ class DLParser(object):
1569
1823
  + rbrace
1570
1824
  )
1571
1825
  .set_results_name("fuzzy_ranges", list_all_matches=True)
1572
- .set_parse_action(partial(_parse_fuzzy_number_range, kb))
1826
+ .set_parse_action(DLParser._parse_fuzzy_number_range)
1573
1827
  )
1574
1828
 
1575
1829
  features = (
@@ -1598,15 +1852,29 @@ class DLParser(object):
1598
1852
  + rbrace
1599
1853
  )
1600
1854
  .set_results_name("features", list_all_matches=True)
1601
- .set_parse_action(partial(_parse_feature, kb))
1855
+ .set_parse_action(DLParser._parse_feature)
1856
+ )
1857
+
1858
+ term = (
1859
+ pp.infix_notation(
1860
+ numbers | variables,
1861
+ [
1862
+ (FuzzyDLKeyword.MUL.get_value(), 2, pp.OpAssoc.LEFT),
1863
+ ],
1864
+ )
1865
+ .set_results_name("term", list_all_matches=True)
1866
+ .set_parse_action(DLParser._parse_term)
1602
1867
  )
1603
1868
 
1604
1869
  expression = (
1605
- pp.DelimitedList(
1606
- numbers + FuzzyDLKeyword.MUL.get_value() + variables, delim="+"
1870
+ # pp.DelimitedList(
1871
+ # numbers + FuzzyDLKeyword.MUL.get_value() + variables, delim="+"
1872
+ # )
1873
+ pp.infix_notation(
1874
+ term, [(FuzzyDLKeyword.SUM.get_value(), 2, pp.OpAssoc.LEFT)]
1607
1875
  )
1608
1876
  .set_results_name("expressions", list_all_matches=True)
1609
- .set_parse_action(partial(_parse_expression, kb))
1877
+ .set_parse_action(DLParser._parse_expression)
1610
1878
  )
1611
1879
 
1612
1880
  inequation = (
@@ -1622,119 +1890,118 @@ class DLParser(object):
1622
1890
  + numbers
1623
1891
  )
1624
1892
  .set_results_name("inequations", list_all_matches=True)
1625
- .set_parse_action(partial(_parse_inequation, kb))
1893
+ .set_parse_action(DLParser._parse_inequation)
1626
1894
  )
1627
1895
 
1628
1896
  constraints = (
1629
1897
  (
1630
1898
  lbrace
1899
+ + FuzzyDLKeyword.CONSTRAINTS.get_value()
1900
+ + lbrace
1631
1901
  + (
1632
1902
  inequation
1633
1903
  | FuzzyDLKeyword.BINARY.get_value() + variables
1634
1904
  | FuzzyDLKeyword.FREE.get_value() + variables
1635
1905
  )
1636
1906
  + rbrace
1907
+ + rbrace
1637
1908
  )
1638
1909
  .set_results_name("constraints", list_all_matches=True)
1639
- .set_parse_action(partial(_parse_constraints, kb))
1910
+ .set_parse_action(DLParser._parse_constraints)
1640
1911
  )
1641
1912
 
1642
1913
  show_concrete_fillers = (
1643
1914
  (
1644
1915
  lbrace
1645
1916
  + FuzzyDLKeyword.SHOW_CONCRETE_FILLERS.get_value().suppress()
1646
- + pp.OneOrMore(variables)
1917
+ + variables[1, ...]
1647
1918
  + rbrace
1648
1919
  )
1649
1920
  .set_results_name("show_concrete_fillers", list_all_matches=True)
1650
- .set_parse_action(partial(_show_concrete_fillers, kb))
1921
+ .set_parse_action(DLParser._show_concrete_fillers)
1651
1922
  )
1652
1923
 
1653
1924
  show_concrete_fillers_for = (
1654
1925
  (
1655
1926
  lbrace
1656
1927
  + FuzzyDLKeyword.SHOW_CONCRETE_FILLERS_FOR.get_value().suppress()
1657
- + variables
1658
- + pp.OneOrMore(variables)
1928
+ + variables[2, ...]
1659
1929
  + rbrace
1660
1930
  )
1661
1931
  .set_results_name("show_concrete_fillers_for", list_all_matches=True)
1662
- .set_parse_action(partial(_show_concrete_fillers_for, kb))
1932
+ .set_parse_action(DLParser._show_concrete_fillers_for)
1663
1933
  )
1664
1934
 
1665
1935
  show_concrete_instance_for = (
1666
1936
  (
1667
1937
  lbrace
1668
1938
  + FuzzyDLKeyword.SHOW_CONCRETE_INSTANCE_FOR.get_value().suppress()
1669
- + variables
1670
- + variables
1671
- + pp.OneOrMore(variables)
1939
+ + variables[3, ...]
1672
1940
  + rbrace
1673
1941
  )
1674
1942
  .set_results_name("show_concrete_instance_for", list_all_matches=True)
1675
- .set_parse_action(partial(_show_concrete_instance_for, kb))
1943
+ .set_parse_action(DLParser._show_concrete_instance_for)
1676
1944
  )
1677
1945
 
1678
1946
  show_abstract_fillers = (
1679
1947
  (
1680
1948
  lbrace
1681
1949
  + FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS.get_value().suppress()
1682
- + pp.OneOrMore(variables)
1950
+ + variables[1, ...]
1683
1951
  + rbrace
1684
1952
  )
1685
1953
  .set_results_name("show_abstract_fillers", list_all_matches=True)
1686
- .set_parse_action(partial(_show_abstract_fillers, kb))
1954
+ .set_parse_action(DLParser._show_abstract_fillers)
1687
1955
  )
1688
1956
 
1689
1957
  show_abstract_fillers_for = (
1690
1958
  (
1691
1959
  lbrace
1692
1960
  + FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS_FOR.get_value().suppress()
1693
- + variables
1694
- + pp.OneOrMore(variables)
1961
+ + variables[2, ...]
1695
1962
  + rbrace
1696
1963
  )
1697
1964
  .set_results_name("show_abstract_fillers_for", list_all_matches=True)
1698
- .set_parse_action(partial(_show_abstract_fillers_for, kb))
1965
+ .set_parse_action(DLParser._show_abstract_fillers_for)
1699
1966
  )
1700
1967
 
1701
1968
  show_concepts = (
1702
1969
  (
1703
1970
  lbrace
1704
1971
  + FuzzyDLKeyword.SHOW_CONCEPTS.get_value().suppress()
1705
- + pp.OneOrMore(variables)
1972
+ + variables[1, ...]
1706
1973
  + rbrace
1707
1974
  )
1708
1975
  .set_results_name("show_concepts", list_all_matches=True)
1709
- .set_parse_action(partial(_show_concepts, kb))
1976
+ .set_parse_action(DLParser._show_concepts)
1710
1977
  )
1711
1978
 
1712
1979
  show_instances = (
1713
1980
  (
1714
1981
  lbrace
1715
1982
  + FuzzyDLKeyword.SHOW_INSTANCES.get_value().suppress()
1716
- + pp.OneOrMore(concept)
1983
+ + concept[1, ...]
1717
1984
  + rbrace
1718
1985
  )
1719
1986
  .set_results_name("show_instances", list_all_matches=True)
1720
- .set_parse_action(partial(_show_instances, kb))
1987
+ .set_parse_action(DLParser._show_instances)
1721
1988
  )
1722
1989
 
1723
1990
  show_variables = (
1724
1991
  (
1725
1992
  lbrace
1726
1993
  + FuzzyDLKeyword.SHOW_VARIABLES.get_value().suppress()
1727
- + pp.OneOrMore(variables)
1994
+ + variables[1, ...]
1728
1995
  + rbrace
1729
1996
  )
1730
1997
  .set_results_name("show_variables", list_all_matches=True)
1731
- .set_parse_action(partial(_show_variables, kb))
1998
+ .set_parse_action(DLParser._show_variables)
1732
1999
  )
1733
2000
 
1734
2001
  show_languages = (
1735
2002
  (lbrace + FuzzyDLKeyword.SHOW_LANGUAGE.get_value().suppress() + rbrace)
1736
2003
  .set_results_name("show_languages", list_all_matches=True)
1737
- .set_parse_action(partial(_show_languages, kb))
2004
+ .set_parse_action(DLParser._show_languages)
1738
2005
  )
1739
2006
 
1740
2007
  show_statements = (
@@ -1756,11 +2023,11 @@ class DLParser(object):
1756
2023
  FuzzyDLKeyword.CRISP_CONCEPT.get_value()
1757
2024
  | FuzzyDLKeyword.CRISP_ROLE.get_value()
1758
2025
  )
1759
- + pp.OneOrMore(variables)
2026
+ + variables[1, ...]
1760
2027
  + rbrace
1761
2028
  )
1762
2029
  .set_results_name("crisp_declarations", list_all_matches=True)
1763
- .set_parse_action(partial(_parse_crisp_declarations, kb))
2030
+ .set_parse_action(DLParser._parse_crisp_declarations)
1764
2031
  )
1765
2032
 
1766
2033
  fuzzy_similarity = (
@@ -1771,7 +2038,7 @@ class DLParser(object):
1771
2038
  + rbrace
1772
2039
  )
1773
2040
  .set_results_name("fuzzy_similarities", list_all_matches=True)
1774
- .set_parse_action(partial(_parse_fuzzy_similarity, kb))
2041
+ .set_parse_action(DLParser._parse_fuzzy_similarity)
1775
2042
  )
1776
2043
 
1777
2044
  fuzzy_equivalence = (
@@ -1782,13 +2049,13 @@ class DLParser(object):
1782
2049
  + rbrace
1783
2050
  )
1784
2051
  .set_results_name("fuzzy_equivalences", list_all_matches=True)
1785
- .set_parse_action(partial(_parse_fuzzy_equivalence, kb))
2052
+ .set_parse_action(DLParser._parse_fuzzy_equivalence)
1786
2053
  )
1787
2054
 
1788
2055
  degree = (
1789
2056
  (numbers | expression | variables)
1790
2057
  .set_results_name("degrees", list_all_matches=True)
1791
- .set_parse_action(partial(_parse_degree, kb))
2058
+ .set_parse_action(DLParser._parse_degree)
1792
2059
  )
1793
2060
 
1794
2061
  axioms = (
@@ -1799,34 +2066,29 @@ class DLParser(object):
1799
2066
  + variables
1800
2067
  + concept
1801
2068
  + pp.Opt(degree)
1802
- | FuzzyDLKeyword.RELATED.get_value()
1803
- + variables
1804
- + variables
1805
- + variables
1806
- + pp.Opt(degree)
2069
+ | FuzzyDLKeyword.RELATED.get_value() + variables[3] + pp.Opt(degree)
1807
2070
  | FuzzyDLKeyword.IMPLIES_ROLE.get_value()
1808
- + variables
1809
- + variables
2071
+ + variables[2]
1810
2072
  + pp.Opt(numbers)
1811
2073
  | FuzzyDLKeyword.ZADEH_IMPLIES.get_value() + concept + concept
1812
2074
  | pp.one_of(
1813
2075
  [
2076
+ FuzzyDLKeyword.ZADEH_IMPLIES.get_name(),
1814
2077
  FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
1815
2078
  FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
1816
2079
  FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
1817
2080
  FuzzyDLKeyword.IMPLIES.get_name(),
1818
2081
  ]
1819
2082
  )
1820
- + concept
1821
- + concept
2083
+ + concept[2]
1822
2084
  + pp.Opt(degree)
1823
2085
  | FuzzyDLKeyword.DEFINE_CONCEPT.get_value() + variables + concept
1824
2086
  | FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT.get_value()
1825
2087
  + variables
1826
2088
  + concept
1827
- | FuzzyDLKeyword.EQUIVALENT_CONCEPTS.get_value() + concept + concept
1828
- | FuzzyDLKeyword.DISJOINT_UNION.get_value() + pp.OneOrMore(concept)
1829
- | FuzzyDLKeyword.DISJOINT.get_value() + pp.OneOrMore(concept)
2089
+ | FuzzyDLKeyword.EQUIVALENT_CONCEPTS.get_value() + concept[2]
2090
+ | FuzzyDLKeyword.DISJOINT_UNION.get_value() + concept[1, ...]
2091
+ | FuzzyDLKeyword.DISJOINT.get_value() + concept[1, ...]
1830
2092
  | FuzzyDLKeyword.RANGE.get_value() + variables + concept
1831
2093
  | FuzzyDLKeyword.DOMAIN.get_value() + variables + concept
1832
2094
  | pp.one_of(
@@ -1839,12 +2101,12 @@ class DLParser(object):
1839
2101
  ]
1840
2102
  )
1841
2103
  + variables
1842
- | FuzzyDLKeyword.INVERSE.get_value() + variables + variables,
2104
+ | FuzzyDLKeyword.INVERSE.get_value() + variables[2],
1843
2105
  )
1844
2106
  + rbrace
1845
2107
  )
1846
2108
  .set_results_name("axioms", list_all_matches=True)
1847
- .set_parse_action(partial(_parse_axioms, kb))
2109
+ .set_parse_action(DLParser._parse_axioms)
1848
2110
  )
1849
2111
 
1850
2112
  queries = (
@@ -1873,17 +2135,14 @@ class DLParser(object):
1873
2135
  FuzzyDLKeyword.MIN_KD_SUBS_QUERY.get_name(),
1874
2136
  ]
1875
2137
  )
1876
- + concept
1877
- + concept
2138
+ + concept[2]
1878
2139
  | pp.one_of(
1879
2140
  [
1880
2141
  FuzzyDLKeyword.MAX_RELATED_QUERY.get_name(),
1881
2142
  FuzzyDLKeyword.MIN_RELATED_QUERY.get_name(),
1882
2143
  ]
1883
2144
  )
1884
- + variables
1885
- + variables
1886
- + variables
2145
+ + variables[3]
1887
2146
  | pp.one_of(
1888
2147
  [
1889
2148
  FuzzyDLKeyword.MAX_SAT_QUERY.get_name(),
@@ -1907,14 +2166,13 @@ class DLParser(object):
1907
2166
  ]
1908
2167
  )
1909
2168
  + concept
1910
- + variables
1911
- + variables
2169
+ + variables[2]
1912
2170
  | FuzzyDLKeyword.BNP_QUERY.get_value() + fuzzy_number_expr,
1913
2171
  )
1914
2172
  + rbrace
1915
2173
  )
1916
2174
  .set_results_name("queries", list_all_matches=True)
1917
- .set_parse_action(partial(_parse_queries, kb, queries_list))
2175
+ .set_parse_action(DLParser._parse_queries)
1918
2176
  )
1919
2177
 
1920
2178
  gformula = (
@@ -1940,32 +2198,26 @@ class DLParser(object):
1940
2198
  @staticmethod
1941
2199
  @utils.recursion_unlimited
1942
2200
  def parse_string(
1943
- kb: KnowledgeBase,
1944
- queries: list[Query],
1945
2201
  instring: str,
1946
2202
  ) -> pp.ParseResults:
1947
- return DLParser.get_grammatics(kb, queries).parse_string(
1948
- instring, parse_all=True
1949
- )
2203
+ return DLParser.get_grammatics().parse_string(instring, parse_all=True)
1950
2204
 
1951
2205
  @staticmethod
1952
2206
  @utils.recursion_unlimited
1953
2207
  def parse_string_opt(
1954
- kb: KnowledgeBase,
1955
- queries: list[Query],
1956
2208
  filename: str,
1957
2209
  ) -> pp.ParseResults:
1958
2210
  with open(filename, "r") as file:
1959
2211
  instring = file.read()
1960
2212
 
1961
2213
  if ConfigReader.DEBUG_PRINT:
1962
- return DLParser.get_grammatics(kb, queries).run_tests(
2214
+ return DLParser.get_grammatics().run_tests(
1963
2215
  instring,
1964
2216
  failure_tests=True,
1965
2217
  file=open(os.path.join(LOG_DIR, FILENAME), "w"),
1966
2218
  )
1967
2219
  else:
1968
- return DLParser.get_grammatics(kb, queries).parse_string(instring)
2220
+ return DLParser.get_grammatics().parse_string(instring)
1969
2221
 
1970
2222
  @staticmethod
1971
2223
  def load_config(*args) -> None:
@@ -1976,22 +2228,25 @@ class DLParser(object):
1976
2228
  try:
1977
2229
  starting_time: float = time.perf_counter_ns()
1978
2230
  DLParser.load_config(*args)
1979
- kb: KnowledgeBase = KnowledgeBase()
1980
- queries: list[Query] = []
2231
+ DLParser.kb = KnowledgeBase()
2232
+ DLParser.queries_list = []
1981
2233
  constants.KNOWLEDGE_BASE_SEMANTICS = FuzzyLogic.LUKASIEWICZ
1982
- # with open(args[0], "r") as file:
1983
- # lines = file.readlines()
1984
- # for line in lines:
1985
- # line = line.strip()
1986
- # if line == "":
1987
- # continue
1988
- # if ConfigReader.DEBUG_PRINT:
1989
- # Util.debug(f"Line -> {line}")
1990
- # _ = DLParser.parse_string(kb, queries, line)
1991
- _ = DLParser.parse_string_opt(kb, queries, args[0])
2234
+
2235
+ if ConfigReader.DEBUG_PRINT:
2236
+ with open(args[0], "r") as file:
2237
+ lines = file.readlines()
2238
+ for i, line in enumerate(lines):
2239
+ line = line.strip()
2240
+ if line == "":
2241
+ continue
2242
+ if ConfigReader.DEBUG_PRINT:
2243
+ Util.debug(f"Line -> {line}")
2244
+ _ = DLParser.parse_string(line)
2245
+ else:
2246
+ _ = DLParser.parse_string_opt(args[0])
1992
2247
  ending_time: float = time.perf_counter_ns() - starting_time
1993
2248
  Util.info(f"Knowledge Base parsed in {(ending_time * 1e-9)}s")
1994
- return kb, queries
2249
+ return DLParser.kb, DLParser.queries_list
1995
2250
  except FileNotFoundError as e:
1996
2251
  Util.error(f"Error: File {args[0]} not found.")
1997
2252
  except Exception as e: