fuzzy-dl-owl2 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. fuzzy_dl_owl2/__init__.py +2 -0
  2. fuzzy_dl_owl2/fuzzydl/__init__.py +23 -0
  3. fuzzy_dl_owl2/fuzzydl/assertion/__init__.py +2 -0
  4. fuzzy_dl_owl2/fuzzydl/assertion/assertion.py +72 -0
  5. fuzzy_dl_owl2/fuzzydl/assertion/atomic_assertion.py +19 -0
  6. fuzzy_dl_owl2/fuzzydl/concept/__init__.py +13 -0
  7. fuzzy_dl_owl2/fuzzydl/concept/all_some_concept.py +85 -0
  8. fuzzy_dl_owl2/fuzzydl/concept/approximation_concept.py +147 -0
  9. fuzzy_dl_owl2/fuzzydl/concept/atomic_concept.py +91 -0
  10. fuzzy_dl_owl2/fuzzydl/concept/choquet_integral.py +64 -0
  11. fuzzy_dl_owl2/fuzzydl/concept/concept.py +230 -0
  12. fuzzy_dl_owl2/fuzzydl/concept/concrete/__init__.py +10 -0
  13. fuzzy_dl_owl2/fuzzydl/concept/concrete/crisp_concrete_concept.py +60 -0
  14. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_concrete_concept.py +63 -0
  15. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/__init__.py +1 -0
  16. fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +127 -0
  17. fuzzy_dl_owl2/fuzzydl/concept/concrete/left_concrete_concept.py +70 -0
  18. fuzzy_dl_owl2/fuzzydl/concept/concrete/linear_concrete_concept.py +70 -0
  19. fuzzy_dl_owl2/fuzzydl/concept/concrete/modified_concrete_concept.py +66 -0
  20. fuzzy_dl_owl2/fuzzydl/concept/concrete/right_concrete_concept.py +70 -0
  21. fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +96 -0
  22. fuzzy_dl_owl2/fuzzydl/concept/concrete/triangular_concrete_concept.py +89 -0
  23. fuzzy_dl_owl2/fuzzydl/concept/ext_threshold_concept.py +77 -0
  24. fuzzy_dl_owl2/fuzzydl/concept/has_value_concept.py +51 -0
  25. fuzzy_dl_owl2/fuzzydl/concept/implies_concept.py +144 -0
  26. fuzzy_dl_owl2/fuzzydl/concept/interface/__init__.py +6 -0
  27. fuzzy_dl_owl2/fuzzydl/concept/interface/has_concept_interface.py +17 -0
  28. fuzzy_dl_owl2/fuzzydl/concept/interface/has_concepts_interface.py +18 -0
  29. fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_concept_interface.py +14 -0
  30. fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_interface.py +15 -0
  31. fuzzy_dl_owl2/fuzzydl/concept/interface/has_value_interface.py +21 -0
  32. fuzzy_dl_owl2/fuzzydl/concept/interface/has_weighted_concepts_interface.py +29 -0
  33. fuzzy_dl_owl2/fuzzydl/concept/modified/__init__.py +3 -0
  34. fuzzy_dl_owl2/fuzzydl/concept/modified/linearly_modified_concept.py +32 -0
  35. fuzzy_dl_owl2/fuzzydl/concept/modified/modified_concept.py +59 -0
  36. fuzzy_dl_owl2/fuzzydl/concept/modified/triangularly_modified_concept.py +33 -0
  37. fuzzy_dl_owl2/fuzzydl/concept/negated_nominal.py +42 -0
  38. fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +707 -0
  39. fuzzy_dl_owl2/fuzzydl/concept/owa_concept.py +57 -0
  40. fuzzy_dl_owl2/fuzzydl/concept/qowa_concept.py +62 -0
  41. fuzzy_dl_owl2/fuzzydl/concept/quasi_sugeno_integral.py +46 -0
  42. fuzzy_dl_owl2/fuzzydl/concept/self_concept.py +45 -0
  43. fuzzy_dl_owl2/fuzzydl/concept/string_concept.py +35 -0
  44. fuzzy_dl_owl2/fuzzydl/concept/sugeno_integral.py +83 -0
  45. fuzzy_dl_owl2/fuzzydl/concept/threshold_concept.py +81 -0
  46. fuzzy_dl_owl2/fuzzydl/concept/truth_concept.py +83 -0
  47. fuzzy_dl_owl2/fuzzydl/concept/value_concept.py +67 -0
  48. fuzzy_dl_owl2/fuzzydl/concept/weighted_concept.py +55 -0
  49. fuzzy_dl_owl2/fuzzydl/concept/weighted_max_concept.py +63 -0
  50. fuzzy_dl_owl2/fuzzydl/concept/weighted_min_concept.py +57 -0
  51. fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_concept.py +62 -0
  52. fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_zero_concept.py +62 -0
  53. fuzzy_dl_owl2/fuzzydl/concept_equivalence.py +20 -0
  54. fuzzy_dl_owl2/fuzzydl/concrete_feature.py +94 -0
  55. fuzzy_dl_owl2/fuzzydl/degree/__init__.py +4 -0
  56. fuzzy_dl_owl2/fuzzydl/degree/degree.py +79 -0
  57. fuzzy_dl_owl2/fuzzydl/degree/degree_expression.py +57 -0
  58. fuzzy_dl_owl2/fuzzydl/degree/degree_numeric.py +57 -0
  59. fuzzy_dl_owl2/fuzzydl/degree/degree_variable.py +54 -0
  60. fuzzy_dl_owl2/fuzzydl/domain_axiom.py +8 -0
  61. fuzzy_dl_owl2/fuzzydl/exception/__init__.py +2 -0
  62. fuzzy_dl_owl2/fuzzydl/exception/fuzzy_ontology_exception.py +4 -0
  63. fuzzy_dl_owl2/fuzzydl/exception/inconsistent_ontology_exception.py +4 -0
  64. fuzzy_dl_owl2/fuzzydl/feature_function.py +148 -0
  65. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +920 -0
  66. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2_java.py +953 -0
  67. fuzzy_dl_owl2/fuzzydl/general_concept_inclusion.py +82 -0
  68. fuzzy_dl_owl2/fuzzydl/individual/__init__.py +3 -0
  69. fuzzy_dl_owl2/fuzzydl/individual/created_individual.py +219 -0
  70. fuzzy_dl_owl2/fuzzydl/individual/individual.py +113 -0
  71. fuzzy_dl_owl2/fuzzydl/individual/representative_individual.py +37 -0
  72. fuzzy_dl_owl2/fuzzydl/knowledge_base.py +9037 -0
  73. fuzzy_dl_owl2/fuzzydl/label.py +32 -0
  74. fuzzy_dl_owl2/fuzzydl/milp/__init__.py +7 -0
  75. fuzzy_dl_owl2/fuzzydl/milp/expression.py +186 -0
  76. fuzzy_dl_owl2/fuzzydl/milp/inequation.py +55 -0
  77. fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +787 -0
  78. fuzzy_dl_owl2/fuzzydl/milp/show_variables_helper.py +151 -0
  79. fuzzy_dl_owl2/fuzzydl/milp/solution.py +45 -0
  80. fuzzy_dl_owl2/fuzzydl/milp/term.py +76 -0
  81. fuzzy_dl_owl2/fuzzydl/milp/variable.py +89 -0
  82. fuzzy_dl_owl2/fuzzydl/modifier/__init__.py +3 -0
  83. fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +76 -0
  84. fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +39 -0
  85. fuzzy_dl_owl2/fuzzydl/modifier/triangular_modifier.py +76 -0
  86. fuzzy_dl_owl2/fuzzydl/parser/ParserConstants.py +406 -0
  87. fuzzy_dl_owl2/fuzzydl/parser/__init__.py +1 -0
  88. fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +2029 -0
  89. fuzzy_dl_owl2/fuzzydl/parser/ebnf.lark +290 -0
  90. fuzzy_dl_owl2/fuzzydl/parser/larkx.py +70 -0
  91. fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +81 -0
  92. fuzzy_dl_owl2/fuzzydl/query/__init__.py +14 -0
  93. fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +50 -0
  94. fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +22 -0
  95. fuzzy_dl_owl2/fuzzydl/query/defuzzify/__init__.py +4 -0
  96. fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +76 -0
  97. fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +19 -0
  98. fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +88 -0
  99. fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +20 -0
  100. fuzzy_dl_owl2/fuzzydl/query/instance_query.py +19 -0
  101. fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +32 -0
  102. fuzzy_dl_owl2/fuzzydl/query/max/__init__.py +5 -0
  103. fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +45 -0
  104. fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +31 -0
  105. fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +45 -0
  106. fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +73 -0
  107. fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +64 -0
  108. fuzzy_dl_owl2/fuzzydl/query/min/__init__.py +5 -0
  109. fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +50 -0
  110. fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +31 -0
  111. fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +57 -0
  112. fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +80 -0
  113. fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +65 -0
  114. fuzzy_dl_owl2/fuzzydl/query/query.py +38 -0
  115. fuzzy_dl_owl2/fuzzydl/query/related_query.py +15 -0
  116. fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +37 -0
  117. fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +20 -0
  118. fuzzy_dl_owl2/fuzzydl/range_axiom.py +7 -0
  119. fuzzy_dl_owl2/fuzzydl/relation.py +47 -0
  120. fuzzy_dl_owl2/fuzzydl/restriction/__init__.py +2 -0
  121. fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +16 -0
  122. fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +34 -0
  123. fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +10 -0
  124. fuzzy_dl_owl2/fuzzydl/util/__init__.py +3 -0
  125. fuzzy_dl_owl2/fuzzydl/util/config_reader.py +56 -0
  126. fuzzy_dl_owl2/fuzzydl/util/constants.py +424 -0
  127. fuzzy_dl_owl2/fuzzydl/util/util.py +73 -0
  128. fuzzy_dl_owl2/fuzzyowl2/__init__.py +5 -0
  129. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +1513 -0
  130. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_java.py +1409 -0
  131. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl.py +917 -0
  132. fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl_java.py +956 -0
  133. fuzzy_dl_owl2/fuzzyowl2/owl_types/__init__.py +0 -0
  134. fuzzy_dl_owl2/fuzzyowl2/owl_types/choquet_concept.py +19 -0
  135. fuzzy_dl_owl2/fuzzyowl2/owl_types/concept_definition.py +14 -0
  136. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_datatype.py +22 -0
  137. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_modifier.py +4 -0
  138. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_nominal_concept.py +19 -0
  139. fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_property.py +5 -0
  140. fuzzy_dl_owl2/fuzzyowl2/owl_types/left_shoulder_function.py +17 -0
  141. fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_function.py +17 -0
  142. fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_modifier.py +13 -0
  143. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_concept.py +19 -0
  144. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_function.py +17 -0
  145. fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_property.py +15 -0
  146. fuzzy_dl_owl2/fuzzyowl2/owl_types/owa_concept.py +19 -0
  147. fuzzy_dl_owl2/fuzzyowl2/owl_types/property_definition.py +10 -0
  148. fuzzy_dl_owl2/fuzzyowl2/owl_types/qowa_concept.py +19 -0
  149. fuzzy_dl_owl2/fuzzyowl2/owl_types/quasi_sugeno_concept.py +21 -0
  150. fuzzy_dl_owl2/fuzzyowl2/owl_types/right_shoulder_function.py +17 -0
  151. fuzzy_dl_owl2/fuzzyowl2/owl_types/sugeno_concept.py +21 -0
  152. fuzzy_dl_owl2/fuzzyowl2/owl_types/trapezoidal_function.py +25 -0
  153. fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_function.py +21 -0
  154. fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_modifer.py +21 -0
  155. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_concept.py +19 -0
  156. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_max_concept.py +15 -0
  157. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_min_concept.py +15 -0
  158. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_concept.py +15 -0
  159. fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_zero_concept.py +15 -0
  160. fuzzy_dl_owl2/fuzzyowl2/parser/__init__.py +1 -0
  161. fuzzy_dl_owl2/fuzzyowl2/parser/owl2_parser.py +491 -0
  162. fuzzy_dl_owl2/fuzzyowl2/util/__init__.py +1 -0
  163. fuzzy_dl_owl2/fuzzyowl2/util/constants.py +112 -0
  164. fuzzy_dl_owl2-1.0.0.dist-info/LICENSE +427 -0
  165. fuzzy_dl_owl2-1.0.0.dist-info/METADATA +299 -0
  166. fuzzy_dl_owl2-1.0.0.dist-info/RECORD +167 -0
  167. fuzzy_dl_owl2-1.0.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,2029 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime
4
+ import os
5
+ import time
6
+ import traceback
7
+ import typing
8
+ from functools import partial, reduce
9
+
10
+ import pyparsing as pp
11
+
12
+ from fuzzy_dl_owl2.fuzzydl.concept.all_some_concept import AllSomeConcept
13
+ from fuzzy_dl_owl2.fuzzydl.concept.approximation_concept import \
14
+ ApproximationConcept
15
+ from fuzzy_dl_owl2.fuzzydl.concept.choquet_integral import ChoquetIntegral
16
+ 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
37
+ from fuzzy_dl_owl2.fuzzydl.concept.has_value_concept import HasValueConcept
38
+ from fuzzy_dl_owl2.fuzzydl.concept.implies_concept import ImpliesConcept
39
+ from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
40
+ from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
41
+ from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
42
+ from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import \
43
+ QsugenoIntegral
44
+ from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
45
+ from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
46
+ from fuzzy_dl_owl2.fuzzydl.concept.threshold_concept import ThresholdConcept
47
+ from fuzzy_dl_owl2.fuzzydl.concept.truth_concept import TruthConcept
48
+ 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
57
+ from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
58
+ from fuzzy_dl_owl2.fuzzydl.degree.degree_expression import DegreeExpression
59
+ from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
60
+ from fuzzy_dl_owl2.fuzzydl.degree.degree_variable import DegreeVariable
61
+ from fuzzy_dl_owl2.fuzzydl.exception.inconsistent_ontology_exception import \
62
+ InconsistentOntologyException
63
+ from fuzzy_dl_owl2.fuzzydl.feature_function import FeatureFunction
64
+ from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
65
+ from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
66
+ from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
67
+ from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
68
+ from fuzzy_dl_owl2.fuzzydl.milp.term import Term
69
+ from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
70
+ from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
71
+ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
72
+ from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import \
73
+ TriangularModifier
74
+ from fuzzy_dl_owl2.fuzzydl.query.all_instances_query import AllInstancesQuery
75
+ 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
86
+ from fuzzy_dl_owl2.fuzzydl.query.max.max_query import MaxQuery
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
94
+ from fuzzy_dl_owl2.fuzzydl.query.min.min_query import MinQuery
95
+ 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
100
+ from fuzzy_dl_owl2.fuzzydl.query.query import Query
101
+ from fuzzy_dl_owl2.fuzzydl.util import constants, utils
102
+ 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)
108
+ from fuzzy_dl_owl2.fuzzydl.util.util import Util
109
+
110
+ TODAY: datetime.datetime = datetime.datetime.today()
111
+ LOG_DIR: str = os.path.join(
112
+ ".", "logs", "parser", str(TODAY.year), str(TODAY.month), str(TODAY.day)
113
+ )
114
+ FILENAME: str = (
115
+ f"fuzzydl_{str(TODAY.hour).zfill(2)}-{str(TODAY.minute).zfill(2)}-{str(TODAY.second).zfill(2)}.log"
116
+ )
117
+
118
+ if not os.path.exists(LOG_DIR):
119
+ os.makedirs(LOG_DIR)
120
+
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:
181
+ return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
182
+ elif kb.get_logic() == FuzzyLogic.ZADEH:
183
+ 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:
206
+ return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
207
+ elif kb.get_logic() == FuzzyLogic.ZADEH:
208
+ 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:
235
+ return pp.ParseResults(
236
+ [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
237
+ )
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."
242
+ )
243
+ elif operator == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
244
+ Util.error(
245
+ "Error: LUKASIEWICZ_IMPLIES cannot be used under classical reasoner."
246
+ )
247
+ elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
248
+ Util.error(
249
+ "Error: ZADEH_IMPLIES cannot be used under classical reasoner."
250
+ )
251
+ elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
252
+ Util.error(
253
+ "Error: KLEENE_DIENES_IMPLIES cannot be used under classical reasoner."
254
+ )
255
+ if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
256
+ return pp.ParseResults(
257
+ [ImpliesConcept.goedel_implies(list_tokens[0], list_tokens[1])]
258
+ )
259
+ elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
260
+ return pp.ParseResults(
261
+ [ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
262
+ )
263
+ elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
264
+ return pp.ParseResults(
265
+ [ImpliesConcept.kleene_dienes_implies(list_tokens[0], list_tokens[1])]
266
+ )
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)]
299
+ )
300
+ elif operator == FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION:
301
+ return pp.ParseResults(
302
+ [ApproximationConcept.tight_lower_approx(role, concept)]
303
+ )
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)]
311
+ )
312
+ elif operator == FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION:
313
+ return pp.ParseResults(
314
+ [ApproximationConcept.loose_lower_approx(role, concept)]
315
+ )
316
+ return tokens
317
+
318
+
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)):
356
+ return pp.ParseResults(
357
+ [ThresholdConcept.pos_threshold(list_tokens[1], concept)]
358
+ )
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
+ ]
366
+ )
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)]
371
+ )
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
+ ]
379
+ )
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
+ ]
390
+ )
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."
588
+ )
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)):
617
+ return pp.ParseResults(
618
+ [TriangularFuzzyNumber(tokens[0], tokens[0], tokens[0])]
619
+ )
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."
624
+ )
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])
708
+ )
709
+ elif "+" in tokens:
710
+ return FeatureFunction(
711
+ FeatureFunction(list(map(FeatureFunction, tokens[::2])))
712
+ )
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]):
737
+ return pp.ParseResults(
738
+ [
739
+ kb.add_datatype_restriction(
740
+ restriction_type, kb.get_concept(list_tokens[2]), role
741
+ )
742
+ ]
743
+ )
744
+ else:
745
+ v: Variable = Variable(list_tokens[2], VariableType.CONTINUOUS)
746
+ return pp.ParseResults(
747
+ [kb.add_datatype_restriction(restriction_type, v, role)]
748
+ )
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():
755
+ return pp.ParseResults(
756
+ [
757
+ kb.add_datatype_restriction(
758
+ restriction_type, list_tokens[2].get_a(), role
759
+ )
760
+ ]
761
+ )
762
+ else:
763
+ return pp.ParseResults(
764
+ [kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
765
+ )
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
771
+
772
+
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]
781
+ 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
803
+ )
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:
832
+ Util.error(
833
+ "Error: show-concrete-fillers can only be used with concrete roles."
834
+ )
835
+ return tokens
836
+
837
+
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]))]
999
+ )
1000
+ return tokens
1001
+
1002
+
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}")
1006
+
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,
1163
+ ):
1164
+ if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
1165
+ queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
1166
+ else:
1167
+ queries_list.append(_class(c1, c2, LogicOperatorType.ZADEH))
1168
+ elif list_tokens[0] in (
1169
+ FuzzyDLKeyword.MAX_G_SUBS_QUERY,
1170
+ FuzzyDLKeyword.MIN_G_SUBS_QUERY,
1171
+ ):
1172
+ queries_list.append(_class(c1, c2, LogicOperatorType.GOEDEL))
1173
+ elif list_tokens[0] in (
1174
+ FuzzyDLKeyword.MAX_L_SUBS_QUERY,
1175
+ FuzzyDLKeyword.MIN_L_SUBS_QUERY,
1176
+ ):
1177
+ queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
1178
+ elif list_tokens[0] in (
1179
+ FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
1180
+ FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
1181
+ ):
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."
1221
+ )
1222
+ queries_list.append(BnpQuery(list_tokens[1]))
1223
+ return tokens
1224
+
1225
+
1226
+ class DLParser(object):
1227
+
1228
+ @staticmethod
1229
+ def get_grammatics(
1230
+ kb: KnowledgeBase, queries_list: list[Query]
1231
+ ) -> pp.ParserElement:
1232
+ """
1233
+ This function generate the grammatics to parse the predicate wih formula "formula".
1234
+
1235
+ Parameters
1236
+ ---------------------------
1237
+ formula := The predicate formula used for the parsing.
1238
+
1239
+ Returns
1240
+ ---------------------------
1241
+ The parsed result given by pyparsing.
1242
+ """
1243
+ pp.ParserElement.enable_left_recursion(force=True)
1244
+
1245
+ lbrace = pp.Literal("(").set_results_name("lbrace").suppress()
1246
+ rbrace = pp.Literal(")").set_results_name("rbrace").suppress()
1247
+ comment = pp.one_of(["#", "%"]).set_results_name("comment").suppress()
1248
+ any_not_newline = (
1249
+ pp.Regex("[^\n]+").set_results_name("any_not_newline").suppress()
1250
+ )
1251
+
1252
+ digits = pp.Word(pp.nums)
1253
+ numbers = (
1254
+ pp.Combine(pp.Opt(pp.one_of(["+", "-"])) + digits + pp.Opt("." + digits))
1255
+ .set_results_name("number", list_all_matches=True)
1256
+ .set_parse_action(_to_number)
1257
+ )
1258
+
1259
+ simple_string = pp.Word(pp.alphas + "_", pp.alphanums + "_'").set_results_name(
1260
+ "string", list_all_matches=True
1261
+ ) # pp.Regex(r"[a-zA-Z_][a-zA-Z0-9_]*")
1262
+ strings = (
1263
+ pp.Opt(pp.one_of(['"', "'"])).suppress()
1264
+ + simple_string.set_results_name("string", list_all_matches=True)
1265
+ + pp.Opt(pp.one_of(['"', "'"])).suppress()
1266
+ )
1267
+ variables = (
1268
+ strings | simple_string.set_results_name("variable", list_all_matches=True)
1269
+ ).set_results_name("variables", list_all_matches=True)
1270
+
1271
+ fuzzy_logic = (
1272
+ (
1273
+ lbrace
1274
+ + FuzzyDLKeyword.DEFINE_FUZZY_LOGIC.get_value().suppress()
1275
+ + (
1276
+ FuzzyDLKeyword.LUKASIEWICZ.get_value()
1277
+ | FuzzyDLKeyword.ZADEH.get_value()
1278
+ | FuzzyDLKeyword.CLASSICAL.get_value()
1279
+ ).set_results_name("fuzzy_logic")
1280
+ + rbrace
1281
+ )
1282
+ .set_results_name("fuzzy_logics", list_all_matches=True)
1283
+ .add_parse_action(partial(_fuzzy_logic_parser, kb))
1284
+ )
1285
+
1286
+ comment_line = (comment + any_not_newline).set_results_name(
1287
+ "comments", list_all_matches=True
1288
+ )
1289
+
1290
+ concept = pp.Forward()
1291
+
1292
+ weighted_concept_part = (
1293
+ (lbrace + numbers + concept + rbrace)
1294
+ .set_results_name("simple_weighted_concepts_single", list_all_matches=True)
1295
+ .set_parse_action(partial(_parse_weighted_concept_simple, kb))
1296
+ )
1297
+
1298
+ simple_fuzzy_number = (
1299
+ (variables | lbrace + numbers[3] + rbrace | numbers)
1300
+ .set_results_name("simple_fuzzy_numbers", list_all_matches=True)
1301
+ .set_parse_action(partial(_create_fuzzy_number, kb))
1302
+ )
1303
+
1304
+ fuzzy_number_expr = pp.Forward()
1305
+ fuzzy_number_expr <<= (
1306
+ simple_fuzzy_number
1307
+ | lbrace
1308
+ + pp.one_of(
1309
+ [
1310
+ FuzzyDLKeyword.FEATURE_SUM.get_name(),
1311
+ FuzzyDLKeyword.FEATURE_MUL.get_name(),
1312
+ ]
1313
+ )
1314
+ + pp.OneOrMore(fuzzy_number_expr)
1315
+ + rbrace
1316
+ | lbrace
1317
+ + pp.one_of(
1318
+ [
1319
+ FuzzyDLKeyword.FEATURE_DIV.get_name(),
1320
+ FuzzyDLKeyword.FEATURE_SUB.get_name(),
1321
+ ]
1322
+ )
1323
+ + fuzzy_number_expr[2]
1324
+ + rbrace
1325
+ ).set_results_name("fuzzy_number_expressions", list_all_matches=True)
1326
+
1327
+ fuzzy_numbers = (
1328
+ (
1329
+ lbrace
1330
+ + FuzzyDLKeyword.DEFINE_FUZZY_NUMBER.get_value().suppress()
1331
+ + variables
1332
+ + fuzzy_number_expr
1333
+ + rbrace
1334
+ )
1335
+ .set_results_name("fuzzy_numbers", list_all_matches=True)
1336
+ .set_parse_action(partial(_set_fuzzy_number, kb))
1337
+ )
1338
+
1339
+ datatype_restriction_function = (
1340
+ (
1341
+ variables
1342
+ | 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
+ )
1347
+ .set_results_name("restrictions", list_all_matches=True)
1348
+ .set_parse_action(partial(_parse_restrictions, kb))
1349
+ )
1350
+
1351
+ datatype_restrictions = (
1352
+ (
1353
+ lbrace
1354
+ + pp.one_of(
1355
+ [
1356
+ FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
1357
+ FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
1358
+ FuzzyDLKeyword.EQUALS.get_name(),
1359
+ ]
1360
+ )
1361
+ + variables
1362
+ + (variables | datatype_restriction_function | fuzzy_number_expr)
1363
+ + rbrace
1364
+ )
1365
+ .set_results_name("datatype_restrictions", list_all_matches=True)
1366
+ .set_parse_action(partial(_parse_datatype_restriction, kb))
1367
+ )
1368
+
1369
+ concept <<= (
1370
+ (
1371
+ variables
1372
+ | FuzzyDLKeyword.TOP.get_value()
1373
+ | FuzzyDLKeyword.BOTTOM.get_value()
1374
+ )
1375
+ .set_results_name("truth_constants", list_all_matches=True)
1376
+ .set_parse_action(partial(_to_top_bottom_concept, kb))
1377
+ | datatype_restrictions.set_results_name(
1378
+ "restriction_concepts", list_all_matches=True
1379
+ )
1380
+ | weighted_concept_part.set_results_name(
1381
+ "simple_weighted_concept", list_all_matches=True
1382
+ )
1383
+ | lbrace
1384
+ + (
1385
+ (
1386
+ (
1387
+ pp.one_of(
1388
+ [
1389
+ FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
1390
+ FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
1391
+ ]
1392
+ )
1393
+ + (variables | numbers)
1394
+ + concept
1395
+ )
1396
+ .set_results_name("threshold_concepts", list_all_matches=True)
1397
+ .set_parse_action(partial(_parse_threshold_concept, kb))
1398
+ | (
1399
+ pp.one_of(
1400
+ [
1401
+ FuzzyDLKeyword.AND.get_name(),
1402
+ FuzzyDLKeyword.GOEDEL_AND.get_name(),
1403
+ FuzzyDLKeyword.LUKASIEWICZ_AND.get_name(),
1404
+ FuzzyDLKeyword.OR.get_name(),
1405
+ FuzzyDLKeyword.GOEDEL_OR.get_name(),
1406
+ FuzzyDLKeyword.LUKASIEWICZ_OR.get_name(),
1407
+ FuzzyDLKeyword.IMPLIES.get_name(),
1408
+ FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
1409
+ FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
1410
+ FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
1411
+ ]
1412
+ )
1413
+ + concept[2, ...]
1414
+ ).set_results_name("implies_concepts", list_all_matches=True)
1415
+ | (
1416
+ FuzzyDLKeyword.SOME.get_value()
1417
+ + variables
1418
+ + (variables | concept)
1419
+ ).set_results_name("some_concepts", list_all_matches=True)
1420
+ | (
1421
+ FuzzyDLKeyword.HAS_VALUE.get_value() + variables + variables
1422
+ ).set_results_name("has_value_concepts", list_all_matches=True)
1423
+ | pp.one_of(
1424
+ [
1425
+ FuzzyDLKeyword.ALL.get_name(),
1426
+ FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION.get_name(),
1427
+ FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION.get_name(),
1428
+ FuzzyDLKeyword.UPPER_APPROXIMATION.get_name(),
1429
+ FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION.get_name(),
1430
+ FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION.get_name(),
1431
+ FuzzyDLKeyword.LOWER_APPROXIMATION.get_name(),
1432
+ ]
1433
+ )
1434
+ + variables
1435
+ + concept
1436
+ )
1437
+ .set_results_name("binary_concepts", list_all_matches=True)
1438
+ .set_parse_action(partial(_parse_binary_concept, kb))
1439
+ | (
1440
+ FuzzyDLKeyword.NOT.get_value() + concept
1441
+ | FuzzyDLKeyword.SELF.get_value() + variables
1442
+ )
1443
+ .set_results_name("unary_concepts", list_all_matches=True)
1444
+ .set_parse_action(partial(_parse_unary_concept, kb))
1445
+ | (variables + concept)
1446
+ .set_results_name("modifier_concepts", list_all_matches=True)
1447
+ .set_parse_action(partial(_parse_modifier_concept, kb))
1448
+ | (
1449
+ pp.one_of(
1450
+ [
1451
+ FuzzyDLKeyword.W_SUM_ZERO.get_name(),
1452
+ FuzzyDLKeyword.W_SUM.get_name(),
1453
+ FuzzyDLKeyword.W_MAX.get_name(),
1454
+ FuzzyDLKeyword.W_MIN.get_name(),
1455
+ ]
1456
+ )
1457
+ + pp.OneOrMore(weighted_concept_part)
1458
+ )
1459
+ .set_results_name("weighted_concepts", list_all_matches=True)
1460
+ .set_parse_action(partial(_parse_weighted_concept, kb))
1461
+ | (
1462
+ FuzzyDLKeyword.Q_OWA.get_value().suppress()
1463
+ + variables
1464
+ + pp.OneOrMore(concept)
1465
+ )
1466
+ .set_results_name("q_owas", list_all_matches=True)
1467
+ .set_parse_action(partial(_parse_q_owa_concept, kb))
1468
+ | (
1469
+ pp.one_of(
1470
+ [
1471
+ FuzzyDLKeyword.OWA.get_name(),
1472
+ FuzzyDLKeyword.CHOQUET.get_name(),
1473
+ FuzzyDLKeyword.QUASI_SUGENO.get_name(),
1474
+ FuzzyDLKeyword.SUGENO.get_name(),
1475
+ ]
1476
+ )
1477
+ + lbrace
1478
+ + pp.OneOrMore(numbers)
1479
+ + rbrace
1480
+ + lbrace
1481
+ + pp.OneOrMore(concept)
1482
+ + rbrace
1483
+ )
1484
+ .set_results_name("owa_integrals", list_all_matches=True)
1485
+ .set_parse_action(partial(_parse_owa_integral_concept, kb))
1486
+ )
1487
+ + rbrace
1488
+ )
1489
+
1490
+ modifier = (
1491
+ (
1492
+ lbrace
1493
+ + FuzzyDLKeyword.DEFINE_MODIFIER.get_value().suppress()
1494
+ + variables
1495
+ + (
1496
+ FuzzyDLKeyword.LINEAR_MODIFIER.get_value()
1497
+ + lbrace
1498
+ + numbers
1499
+ + rbrace
1500
+ | FuzzyDLKeyword.TRIANGULAR_MODIFIER.get_value()
1501
+ + lbrace
1502
+ + numbers[3]
1503
+ + rbrace
1504
+ )
1505
+ + rbrace
1506
+ )
1507
+ .set_results_name("modifiers", list_all_matches=True)
1508
+ .set_parse_action(partial(_parse_modifier, kb))
1509
+ )
1510
+
1511
+ truth_constants = (
1512
+ (
1513
+ lbrace
1514
+ + FuzzyDLKeyword.DEFINE_TRUTH_CONSTANT.get_value()
1515
+ + variables
1516
+ + numbers
1517
+ + rbrace
1518
+ )
1519
+ .set_results_name("truth_concepts", list_all_matches=True)
1520
+ .set_parse_action(partial(_parse_truth_constants, kb))
1521
+ )
1522
+
1523
+ fuzzy_concept = (
1524
+ (
1525
+ lbrace
1526
+ + FuzzyDLKeyword.DEFINE_FUZZY_CONCEPT.get_value().suppress()
1527
+ + variables
1528
+ + (
1529
+ FuzzyDLKeyword.CRISP.get_value()
1530
+ + lbrace
1531
+ + pp.DelimitedList(numbers, min=4, max=4)
1532
+ + rbrace
1533
+ | FuzzyDLKeyword.LEFT_SHOULDER.get_value()
1534
+ + lbrace
1535
+ + pp.DelimitedList(numbers, min=4, max=4)
1536
+ + rbrace
1537
+ | FuzzyDLKeyword.RIGHT_SHOULDER.get_value()
1538
+ + lbrace
1539
+ + pp.DelimitedList(numbers, min=4, max=4)
1540
+ + rbrace
1541
+ | FuzzyDLKeyword.TRIANGULAR.get_value()
1542
+ + lbrace
1543
+ + pp.DelimitedList(numbers, min=5, max=5)
1544
+ + rbrace
1545
+ | FuzzyDLKeyword.TRAPEZOIDAL.get_value()
1546
+ + lbrace
1547
+ + pp.DelimitedList(numbers, min=6, max=6)
1548
+ + rbrace
1549
+ | FuzzyDLKeyword.LINEAR.get_value()
1550
+ + lbrace
1551
+ + pp.DelimitedList(numbers, min=4, max=4)
1552
+ + rbrace
1553
+ | FuzzyDLKeyword.MODIFIED.get_value()
1554
+ + lbrace
1555
+ + pp.DelimitedList(variables, min=2, max=2)
1556
+ + rbrace
1557
+ )
1558
+ + rbrace
1559
+ )
1560
+ .set_results_name("fuzzy_concepts", list_all_matches=True)
1561
+ .set_parse_action(partial(_parse_fuzzy_concept, kb))
1562
+ )
1563
+
1564
+ fuzzy_range = (
1565
+ (
1566
+ lbrace
1567
+ + FuzzyDLKeyword.DEFINE_FUZZY_NUMBER_RANGE.get_value().suppress()
1568
+ + numbers[2]
1569
+ + rbrace
1570
+ )
1571
+ .set_results_name("fuzzy_ranges", list_all_matches=True)
1572
+ .set_parse_action(partial(_parse_fuzzy_number_range, kb))
1573
+ )
1574
+
1575
+ features = (
1576
+ (
1577
+ lbrace
1578
+ + (
1579
+ # Keyword.FUNCTIONAL.get_value() + variables |
1580
+ FuzzyDLKeyword.RANGE.get_value()
1581
+ + variables
1582
+ + (
1583
+ pp.one_of(
1584
+ [
1585
+ FuzzyDLKeyword.INTEGER.get_name(),
1586
+ FuzzyDLKeyword.REAL.get_name(),
1587
+ ]
1588
+ )
1589
+ + numbers[2]
1590
+ | pp.one_of(
1591
+ [
1592
+ FuzzyDLKeyword.STRING.get_name(),
1593
+ FuzzyDLKeyword.BOOLEAN.get_name(),
1594
+ ]
1595
+ )
1596
+ )
1597
+ )
1598
+ + rbrace
1599
+ )
1600
+ .set_results_name("features", list_all_matches=True)
1601
+ .set_parse_action(partial(_parse_feature, kb))
1602
+ )
1603
+
1604
+ expression = (
1605
+ pp.DelimitedList(
1606
+ numbers + FuzzyDLKeyword.MUL.get_value() + variables, delim="+"
1607
+ )
1608
+ .set_results_name("expressions", list_all_matches=True)
1609
+ .set_parse_action(partial(_parse_expression, kb))
1610
+ )
1611
+
1612
+ inequation = (
1613
+ (
1614
+ expression
1615
+ + pp.one_of(
1616
+ [
1617
+ FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
1618
+ FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
1619
+ FuzzyDLKeyword.EQUALS.get_name(),
1620
+ ]
1621
+ )
1622
+ + numbers
1623
+ )
1624
+ .set_results_name("inequations", list_all_matches=True)
1625
+ .set_parse_action(partial(_parse_inequation, kb))
1626
+ )
1627
+
1628
+ constraints = (
1629
+ (
1630
+ lbrace
1631
+ + (
1632
+ inequation
1633
+ | FuzzyDLKeyword.BINARY.get_value() + variables
1634
+ | FuzzyDLKeyword.FREE.get_value() + variables
1635
+ )
1636
+ + rbrace
1637
+ )
1638
+ .set_results_name("constraints", list_all_matches=True)
1639
+ .set_parse_action(partial(_parse_constraints, kb))
1640
+ )
1641
+
1642
+ show_concrete_fillers = (
1643
+ (
1644
+ lbrace
1645
+ + FuzzyDLKeyword.SHOW_CONCRETE_FILLERS.get_value().suppress()
1646
+ + pp.OneOrMore(variables)
1647
+ + rbrace
1648
+ )
1649
+ .set_results_name("show_concrete_fillers", list_all_matches=True)
1650
+ .set_parse_action(partial(_show_concrete_fillers, kb))
1651
+ )
1652
+
1653
+ show_concrete_fillers_for = (
1654
+ (
1655
+ lbrace
1656
+ + FuzzyDLKeyword.SHOW_CONCRETE_FILLERS_FOR.get_value().suppress()
1657
+ + variables
1658
+ + pp.OneOrMore(variables)
1659
+ + rbrace
1660
+ )
1661
+ .set_results_name("show_concrete_fillers_for", list_all_matches=True)
1662
+ .set_parse_action(partial(_show_concrete_fillers_for, kb))
1663
+ )
1664
+
1665
+ show_concrete_instance_for = (
1666
+ (
1667
+ lbrace
1668
+ + FuzzyDLKeyword.SHOW_CONCRETE_INSTANCE_FOR.get_value().suppress()
1669
+ + variables
1670
+ + variables
1671
+ + pp.OneOrMore(variables)
1672
+ + rbrace
1673
+ )
1674
+ .set_results_name("show_concrete_instance_for", list_all_matches=True)
1675
+ .set_parse_action(partial(_show_concrete_instance_for, kb))
1676
+ )
1677
+
1678
+ show_abstract_fillers = (
1679
+ (
1680
+ lbrace
1681
+ + FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS.get_value().suppress()
1682
+ + pp.OneOrMore(variables)
1683
+ + rbrace
1684
+ )
1685
+ .set_results_name("show_abstract_fillers", list_all_matches=True)
1686
+ .set_parse_action(partial(_show_abstract_fillers, kb))
1687
+ )
1688
+
1689
+ show_abstract_fillers_for = (
1690
+ (
1691
+ lbrace
1692
+ + FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS_FOR.get_value().suppress()
1693
+ + variables
1694
+ + pp.OneOrMore(variables)
1695
+ + rbrace
1696
+ )
1697
+ .set_results_name("show_abstract_fillers_for", list_all_matches=True)
1698
+ .set_parse_action(partial(_show_abstract_fillers_for, kb))
1699
+ )
1700
+
1701
+ show_concepts = (
1702
+ (
1703
+ lbrace
1704
+ + FuzzyDLKeyword.SHOW_CONCEPTS.get_value().suppress()
1705
+ + pp.OneOrMore(variables)
1706
+ + rbrace
1707
+ )
1708
+ .set_results_name("show_concepts", list_all_matches=True)
1709
+ .set_parse_action(partial(_show_concepts, kb))
1710
+ )
1711
+
1712
+ show_instances = (
1713
+ (
1714
+ lbrace
1715
+ + FuzzyDLKeyword.SHOW_INSTANCES.get_value().suppress()
1716
+ + pp.OneOrMore(concept)
1717
+ + rbrace
1718
+ )
1719
+ .set_results_name("show_instances", list_all_matches=True)
1720
+ .set_parse_action(partial(_show_instances, kb))
1721
+ )
1722
+
1723
+ show_variables = (
1724
+ (
1725
+ lbrace
1726
+ + FuzzyDLKeyword.SHOW_VARIABLES.get_value().suppress()
1727
+ + pp.OneOrMore(variables)
1728
+ + rbrace
1729
+ )
1730
+ .set_results_name("show_variables", list_all_matches=True)
1731
+ .set_parse_action(partial(_show_variables, kb))
1732
+ )
1733
+
1734
+ show_languages = (
1735
+ (lbrace + FuzzyDLKeyword.SHOW_LANGUAGE.get_value().suppress() + rbrace)
1736
+ .set_results_name("show_languages", list_all_matches=True)
1737
+ .set_parse_action(partial(_show_languages, kb))
1738
+ )
1739
+
1740
+ show_statements = (
1741
+ show_concrete_fillers_for
1742
+ | show_concrete_fillers
1743
+ | show_concrete_instance_for
1744
+ | show_abstract_fillers_for
1745
+ | show_abstract_fillers
1746
+ | show_concepts
1747
+ | show_instances
1748
+ | show_variables
1749
+ | show_languages
1750
+ )
1751
+
1752
+ crisp_declarations = (
1753
+ (
1754
+ lbrace
1755
+ + (
1756
+ FuzzyDLKeyword.CRISP_CONCEPT.get_value()
1757
+ | FuzzyDLKeyword.CRISP_ROLE.get_value()
1758
+ )
1759
+ + pp.OneOrMore(variables)
1760
+ + rbrace
1761
+ )
1762
+ .set_results_name("crisp_declarations", list_all_matches=True)
1763
+ .set_parse_action(partial(_parse_crisp_declarations, kb))
1764
+ )
1765
+
1766
+ fuzzy_similarity = (
1767
+ (
1768
+ lbrace
1769
+ + FuzzyDLKeyword.DEFINE_FUZZY_SIMILARITY.get_value().suppress()
1770
+ + variables
1771
+ + rbrace
1772
+ )
1773
+ .set_results_name("fuzzy_similarities", list_all_matches=True)
1774
+ .set_parse_action(partial(_parse_fuzzy_similarity, kb))
1775
+ )
1776
+
1777
+ fuzzy_equivalence = (
1778
+ (
1779
+ lbrace
1780
+ + FuzzyDLKeyword.DEFINE_FUZZY_EQUIVALENCE.get_value().suppress()
1781
+ + variables
1782
+ + rbrace
1783
+ )
1784
+ .set_results_name("fuzzy_equivalences", list_all_matches=True)
1785
+ .set_parse_action(partial(_parse_fuzzy_equivalence, kb))
1786
+ )
1787
+
1788
+ degree = (
1789
+ (numbers | expression | variables)
1790
+ .set_results_name("degrees", list_all_matches=True)
1791
+ .set_parse_action(partial(_parse_degree, kb))
1792
+ )
1793
+
1794
+ axioms = (
1795
+ (
1796
+ lbrace
1797
+ + pp.Group(
1798
+ FuzzyDLKeyword.INSTANCE.get_value()
1799
+ + variables
1800
+ + concept
1801
+ + pp.Opt(degree)
1802
+ | FuzzyDLKeyword.RELATED.get_value()
1803
+ + variables
1804
+ + variables
1805
+ + variables
1806
+ + pp.Opt(degree)
1807
+ | FuzzyDLKeyword.IMPLIES_ROLE.get_value()
1808
+ + variables
1809
+ + variables
1810
+ + pp.Opt(numbers)
1811
+ | FuzzyDLKeyword.ZADEH_IMPLIES.get_value() + concept + concept
1812
+ | pp.one_of(
1813
+ [
1814
+ FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
1815
+ FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
1816
+ FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
1817
+ FuzzyDLKeyword.IMPLIES.get_name(),
1818
+ ]
1819
+ )
1820
+ + concept
1821
+ + concept
1822
+ + pp.Opt(degree)
1823
+ | FuzzyDLKeyword.DEFINE_CONCEPT.get_value() + variables + concept
1824
+ | FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT.get_value()
1825
+ + variables
1826
+ + 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)
1830
+ | FuzzyDLKeyword.RANGE.get_value() + variables + concept
1831
+ | FuzzyDLKeyword.DOMAIN.get_value() + variables + concept
1832
+ | pp.one_of(
1833
+ [
1834
+ FuzzyDLKeyword.INVERSE_FUNCTIONAL.get_name(),
1835
+ FuzzyDLKeyword.FUNCTIONAL.get_name(),
1836
+ FuzzyDLKeyword.REFLEXIVE.get_name(),
1837
+ FuzzyDLKeyword.SYMMETRIC.get_name(),
1838
+ FuzzyDLKeyword.TRANSITIVE.get_name(),
1839
+ ]
1840
+ )
1841
+ + variables
1842
+ | FuzzyDLKeyword.INVERSE.get_value() + variables + variables,
1843
+ )
1844
+ + rbrace
1845
+ )
1846
+ .set_results_name("axioms", list_all_matches=True)
1847
+ .set_parse_action(partial(_parse_axioms, kb))
1848
+ )
1849
+
1850
+ queries = (
1851
+ (
1852
+ lbrace
1853
+ + pp.Group(
1854
+ FuzzyDLKeyword.ALL_INSTANCES_QUERY.get_value() + concept
1855
+ | FuzzyDLKeyword.SAT_QUERY.get_value()
1856
+ | pp.one_of(
1857
+ [
1858
+ FuzzyDLKeyword.MAX_INSTANCE_QUERY.get_name(),
1859
+ FuzzyDLKeyword.MIN_INSTANCE_QUERY.get_name(),
1860
+ ]
1861
+ )
1862
+ + variables
1863
+ + concept
1864
+ | pp.one_of(
1865
+ [
1866
+ FuzzyDLKeyword.MAX_SUBS_QUERY.get_name(),
1867
+ FuzzyDLKeyword.MIN_SUBS_QUERY.get_name(),
1868
+ FuzzyDLKeyword.MAX_G_SUBS_QUERY.get_name(),
1869
+ FuzzyDLKeyword.MIN_G_SUBS_QUERY.get_name(),
1870
+ FuzzyDLKeyword.MAX_L_SUBS_QUERY.get_name(),
1871
+ FuzzyDLKeyword.MIN_L_SUBS_QUERY.get_name(),
1872
+ FuzzyDLKeyword.MAX_KD_SUBS_QUERY.get_name(),
1873
+ FuzzyDLKeyword.MIN_KD_SUBS_QUERY.get_name(),
1874
+ ]
1875
+ )
1876
+ + concept
1877
+ + concept
1878
+ | pp.one_of(
1879
+ [
1880
+ FuzzyDLKeyword.MAX_RELATED_QUERY.get_name(),
1881
+ FuzzyDLKeyword.MIN_RELATED_QUERY.get_name(),
1882
+ ]
1883
+ )
1884
+ + variables
1885
+ + variables
1886
+ + variables
1887
+ | pp.one_of(
1888
+ [
1889
+ FuzzyDLKeyword.MAX_SAT_QUERY.get_name(),
1890
+ FuzzyDLKeyword.MIN_SAT_QUERY.get_name(),
1891
+ ]
1892
+ )
1893
+ + concept
1894
+ + pp.Opt(variables)
1895
+ | pp.one_of(
1896
+ [
1897
+ FuzzyDLKeyword.MAX_VAR_QUERY.get_name(),
1898
+ FuzzyDLKeyword.MIN_VAR_QUERY.get_name(),
1899
+ ]
1900
+ )
1901
+ + expression
1902
+ | pp.one_of(
1903
+ [
1904
+ FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY.get_name(),
1905
+ FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY.get_name(),
1906
+ FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY.get_name(),
1907
+ ]
1908
+ )
1909
+ + concept
1910
+ + variables
1911
+ + variables
1912
+ | FuzzyDLKeyword.BNP_QUERY.get_value() + fuzzy_number_expr,
1913
+ )
1914
+ + rbrace
1915
+ )
1916
+ .set_results_name("queries", list_all_matches=True)
1917
+ .set_parse_action(partial(_parse_queries, kb, queries_list))
1918
+ )
1919
+
1920
+ gformula = (
1921
+ comment_line
1922
+ | fuzzy_logic
1923
+ | axioms
1924
+ | truth_constants
1925
+ | modifier
1926
+ | fuzzy_concept
1927
+ | fuzzy_range
1928
+ | fuzzy_numbers
1929
+ | features
1930
+ | constraints
1931
+ | show_statements
1932
+ | crisp_declarations
1933
+ | concept
1934
+ | fuzzy_similarity
1935
+ | fuzzy_equivalence
1936
+ | queries
1937
+ )
1938
+ return pp.OneOrMore(gformula)
1939
+
1940
+ @staticmethod
1941
+ @utils.recursion_unlimited
1942
+ def parse_string(
1943
+ kb: KnowledgeBase,
1944
+ queries: list[Query],
1945
+ instring: str,
1946
+ ) -> pp.ParseResults:
1947
+ return DLParser.get_grammatics(kb, queries).parse_string(
1948
+ instring, parse_all=True
1949
+ )
1950
+
1951
+ @staticmethod
1952
+ @utils.recursion_unlimited
1953
+ def parse_string_opt(
1954
+ kb: KnowledgeBase,
1955
+ queries: list[Query],
1956
+ filename: str,
1957
+ ) -> pp.ParseResults:
1958
+ with open(filename, "r") as file:
1959
+ instring = file.read()
1960
+
1961
+ if ConfigReader.DEBUG_PRINT:
1962
+ return DLParser.get_grammatics(kb, queries).run_tests(
1963
+ instring,
1964
+ failure_tests=True,
1965
+ file=open(os.path.join(LOG_DIR, FILENAME), "w"),
1966
+ )
1967
+ else:
1968
+ return DLParser.get_grammatics(kb, queries).parse_string(instring)
1969
+
1970
+ @staticmethod
1971
+ def load_config(*args) -> None:
1972
+ ConfigReader.load_parameters(os.path.join(os.getcwd(), "CONFIG.ini"), args)
1973
+
1974
+ @staticmethod
1975
+ def get_kb(*args) -> tuple[KnowledgeBase, list[Query]]:
1976
+ try:
1977
+ starting_time: float = time.perf_counter_ns()
1978
+ DLParser.load_config(*args)
1979
+ kb: KnowledgeBase = KnowledgeBase()
1980
+ queries: list[Query] = []
1981
+ 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])
1992
+ ending_time: float = time.perf_counter_ns() - starting_time
1993
+ Util.info(f"Knowledge Base parsed in {(ending_time * 1e-9)}s")
1994
+ return kb, queries
1995
+ except FileNotFoundError as e:
1996
+ Util.error(f"Error: File {args[0]} not found.")
1997
+ except Exception as e:
1998
+ Util.error(e)
1999
+ Util.error(traceback.format_exc())
2000
+
2001
+ @staticmethod
2002
+ def main(*args) -> None:
2003
+ try:
2004
+ kb, queries = DLParser.get_kb(*args)
2005
+ kb.solve_kb()
2006
+ for query in queries:
2007
+ if (
2008
+ isinstance(query, AllInstancesQuery)
2009
+ and not kb.get_individuals().values()
2010
+ ):
2011
+ Util.info(f"{query} -- There are no individuals in the fuzzy KB")
2012
+ else:
2013
+ result: Solution = query.solve(kb)
2014
+ if result.is_consistent_kb():
2015
+ Util.info(f"{query}{result}")
2016
+ else:
2017
+ Util.info("KnowledgeBase inconsistent: Answer is 1.0.")
2018
+ Util.info(f"Time (s): {query.get_total_time()}")
2019
+ if kb.show_language:
2020
+ Util.info(f"The language of the KB is {kb.get_language()}")
2021
+ except InconsistentOntologyException as e:
2022
+ Util.error("KnowledgeBase inconsistent: Any answer is 1.0.")
2023
+ except Exception as e:
2024
+ Util.error(e)
2025
+ Util.error(traceback.format_exc())
2026
+
2027
+
2028
+ if __name__ == "__main__":
2029
+ DLParser.main("./test.txt")