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,787 @@
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ import os
5
+ import typing
6
+
7
+ import gurobipy as gp
8
+ from gurobipy import GRB
9
+
10
+ from fuzzy_dl_owl2.fuzzydl.assertion.assertion import Assertion
11
+ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
12
+ from fuzzy_dl_owl2.fuzzydl.concept.interface.has_value_interface import (
13
+ HasValueInterface,
14
+ )
15
+ from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
16
+ from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
17
+ from fuzzy_dl_owl2.fuzzydl.degree.degree_variable import DegreeVariable
18
+ from fuzzy_dl_owl2.fuzzydl.individual.created_individual import CreatedIndividual
19
+ from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
20
+ from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
21
+ from fuzzy_dl_owl2.fuzzydl.milp.inequation import Inequation
22
+ from fuzzy_dl_owl2.fuzzydl.milp.show_variables_helper import ShowVariablesHelper
23
+ from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
24
+ from fuzzy_dl_owl2.fuzzydl.milp.term import Term
25
+ from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
26
+ from fuzzy_dl_owl2.fuzzydl.relation import Relation
27
+ from fuzzy_dl_owl2.fuzzydl.restriction.restriction import Restriction
28
+ from fuzzy_dl_owl2.fuzzydl.util import constants
29
+ from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
30
+ from fuzzy_dl_owl2.fuzzydl.util.constants import (
31
+ ConceptType,
32
+ InequalityType,
33
+ VariableType,
34
+ )
35
+ from fuzzy_dl_owl2.fuzzydl.util.util import Util
36
+
37
+
38
+ # @utils.singleton
39
+ class MILPHelper:
40
+ PRINT_LABELS: bool = True
41
+ PRINT_VARIABLES: bool = True
42
+
43
+ def __init__(self) -> None:
44
+ self.constraints: list[Inequation] = list()
45
+ self.crisp_concepts: set[str] = set()
46
+ self.crisp_roles: set[str] = set()
47
+ self.number_of_variables: dict[str, int] = dict()
48
+ self.show_vars: ShowVariablesHelper = ShowVariablesHelper()
49
+ self.string_features: set[str] = set()
50
+ self.string_values: dict[int, str] = dict()
51
+ self.variables: list[Variable] = []
52
+
53
+ def clone(self) -> typing.Self:
54
+ milp: MILPHelper = MILPHelper()
55
+ milp.constraints = [c.clone() for c in self.constraints]
56
+ milp.crisp_concepts = copy.deepcopy(self.crisp_concepts)
57
+ milp.crisp_roles = copy.deepcopy(self.crisp_roles)
58
+ milp.number_of_variables = copy.deepcopy(self.number_of_variables)
59
+ milp.show_vars = self.show_vars.clone()
60
+ milp.string_features = copy.deepcopy(self.string_features)
61
+ milp.string_values = copy.deepcopy(self.string_values)
62
+ milp.variables = [v.clone() for v in self.variables]
63
+ return milp
64
+
65
+ def optimize(self, objective: Expression) -> Solution:
66
+ return self.solve_gurobi(objective)
67
+
68
+ @typing.overload
69
+ def print_instance_of_labels(
70
+ self, f_name: str, ind_name: str, value: float
71
+ ) -> None: ...
72
+
73
+ @typing.overload
74
+ def print_instance_of_labels(self, name: str, value: float) -> None: ...
75
+
76
+ def print_instance_of_labels(self, *args) -> None:
77
+ assert len(args) in [2, 3]
78
+ assert isinstance(args[0], str)
79
+ if len(args) == 2:
80
+ assert isinstance(args[1], constants.NUMBER)
81
+ self.__print_instance_of_labels_2(*args)
82
+ else:
83
+ assert isinstance(args[1], str)
84
+ assert isinstance(args[2], constants.NUMBER)
85
+ self.__print_instance_of_labels_1(*args)
86
+
87
+ def __print_instance_of_labels_1(
88
+ self, f_name: str, ind_name: str, value: float
89
+ ) -> None:
90
+ name = f"{f_name}({ind_name})"
91
+ labels = self.show_vars.get_labels(name)
92
+ for f in labels:
93
+ Util.info(
94
+ f"{name} is {f.compute_name()} = {f.get_membership_degree(value)}"
95
+ )
96
+
97
+ def __print_instance_of_labels_2(self, name: str, value: float) -> None:
98
+ labels = self.show_vars.get_labels(name)
99
+ for f in labels:
100
+ Util.info(
101
+ f"{name} is {f.compute_name()} = {f.get_membership_degree(value)}"
102
+ )
103
+
104
+ def get_new_variable(self, v_type: VariableType) -> Variable:
105
+ while True:
106
+ new_var: Variable = Variable.get_new_variable(v_type)
107
+ var_name = str(new_var)
108
+ if var_name not in self.number_of_variables:
109
+ break
110
+
111
+ self.variables.append(new_var)
112
+ self.number_of_variables[var_name] = len(self.variables)
113
+ return new_var
114
+
115
+ @typing.overload
116
+ def get_variable(self, var_name: str) -> Variable: ...
117
+
118
+ @typing.overload
119
+ def get_variable(self, var_name: str, v_type: VariableType) -> Variable: ...
120
+
121
+ @typing.overload
122
+ def get_variable(self, ass: Assertion) -> Variable: ...
123
+
124
+ @typing.overload
125
+ def get_variable(self, rel: Relation) -> Variable: ...
126
+
127
+ @typing.overload
128
+ def get_variable(self, ind: Individual, restrict: Restriction) -> Variable: ...
129
+
130
+ @typing.overload
131
+ def get_variable(self, ind: Individual, c: Concept) -> Variable: ...
132
+
133
+ @typing.overload
134
+ def get_variable(self, ind: Individual, concept_name: str) -> Variable: ...
135
+
136
+ @typing.overload
137
+ def get_variable(self, a: Individual, b: Individual, role: str) -> Variable: ...
138
+
139
+ @typing.overload
140
+ def get_variable(
141
+ self, a: Individual, b: Individual, role: str, v_type: VariableType
142
+ ) -> Variable: ...
143
+
144
+ @typing.overload
145
+ def get_variable(
146
+ self, a: str, b: str, role: str, v_type: VariableType
147
+ ) -> Variable: ...
148
+
149
+ @typing.overload
150
+ def get_variable(self, ind: CreatedIndividual) -> Variable: ...
151
+
152
+ @typing.overload
153
+ def get_variable(self, ind: CreatedIndividual, v_type: VariableType) -> None: ...
154
+
155
+ def get_variable(self, *args) -> Variable:
156
+ assert len(args) in [1, 2, 3, 4]
157
+ if len(args) == 1:
158
+ if isinstance(args[0], str):
159
+ return self.__get_variable_1(*args)
160
+ elif isinstance(args[0], Assertion):
161
+ return self.__get_variable_3(*args)
162
+ elif isinstance(args[0], Relation):
163
+ return self.__get_variable_4(*args)
164
+ elif isinstance(args[0], CreatedIndividual):
165
+ return self.__get_variable_11(*args)
166
+ else:
167
+ raise ValueError
168
+ elif len(args) == 2:
169
+ if isinstance(args[0], str) and isinstance(args[1], VariableType):
170
+ return self.__get_variable_2(*args)
171
+ elif isinstance(args[0], Individual) and isinstance(args[1], Restriction):
172
+ return self.__get_variable_5(*args)
173
+ elif isinstance(args[0], Individual) and isinstance(args[1], Concept):
174
+ return self.__get_variable_6(*args)
175
+ elif isinstance(args[0], CreatedIndividual) and isinstance(
176
+ args[1], VariableType
177
+ ):
178
+ return self.__get_variable_12(*args)
179
+ elif isinstance(args[0], Individual) and isinstance(args[1], str):
180
+ return self.__get_variable_7(*args)
181
+ else:
182
+ raise ValueError
183
+ elif len(args) == 3:
184
+ if (
185
+ isinstance(args[0], Individual)
186
+ and isinstance(args[1], Individual)
187
+ and isinstance(args[2], str)
188
+ ):
189
+ return self.__get_variable_8(*args)
190
+ else:
191
+ raise ValueError
192
+ elif len(args) == 4:
193
+ if (
194
+ isinstance(args[0], Individual)
195
+ and isinstance(args[1], Individual)
196
+ and isinstance(args[2], str)
197
+ and isinstance(args[3], VariableType)
198
+ ):
199
+ return self.__get_variable_9(*args)
200
+ elif (
201
+ isinstance(args[0], str)
202
+ and isinstance(args[1], str)
203
+ and isinstance(args[2], str)
204
+ and isinstance(args[3], VariableType)
205
+ ):
206
+ return self.__get_variable_10(*args)
207
+ else:
208
+ raise ValueError
209
+ else:
210
+ raise ValueError
211
+
212
+ def __get_variable_1(self, var_name: str) -> Variable:
213
+ if var_name in self.number_of_variables:
214
+ for variable in self.variables:
215
+ if str(variable) == var_name:
216
+ return variable
217
+ var: Variable = Variable(var_name, VariableType.SEMI_CONTINUOUS)
218
+ self.variables.append(var)
219
+ self.number_of_variables[str(var)] = len(self.variables)
220
+ return var
221
+
222
+ def __get_variable_2(self, var_name: str, v_type: VariableType) -> Variable:
223
+ var: Variable = self.get_variable(var_name)
224
+ var.set_type(v_type)
225
+ return var
226
+
227
+ def __get_variable_3(self, ass: Assertion) -> Variable:
228
+ return self.get_variable(ass.get_individual(), ass.get_concept())
229
+
230
+ def __get_variable_4(self, rel: Relation) -> Variable:
231
+ a: Individual = rel.get_subject_individual()
232
+ b: Individual = rel.get_object_individual()
233
+ role: str = rel.get_role_name()
234
+ return self.get_variable(a, b, role)
235
+
236
+ def __get_variable_5(self, ind: Individual, restrict: Restriction) -> Variable:
237
+ var: Variable = self.get_variable(f"{ind}:{restrict.get_name_without_degree()}")
238
+ if self.show_vars.show_individuals(str(ind)):
239
+ self.show_vars.add_variable(var, str(var))
240
+ return var
241
+
242
+ def __get_variable_6(self, ind: Individual, c: Concept) -> Variable:
243
+ if c.type == ConceptType.HAS_VALUE:
244
+ assert isinstance(c, HasValueInterface)
245
+
246
+ r: str = c.role
247
+ b: str = str(c.value)
248
+ return self.get_variable(str(ind), b, r, VariableType.SEMI_CONTINUOUS)
249
+ return self.get_variable(ind, str(c))
250
+
251
+ def __get_variable_7(self, ind: Individual, concept_name: str) -> Variable:
252
+ var: Variable = self.get_variable(f"{ind}:{concept_name}")
253
+ if concept_name in self.crisp_concepts:
254
+ var.set_binary_variable()
255
+ if self.show_vars.show_individuals(str(ind)) or self.show_vars.show_concepts(
256
+ concept_name
257
+ ):
258
+ self.show_vars.add_variable(var, str(var))
259
+ return var
260
+
261
+ def __get_variable_8(self, a: Individual, b: Individual, role: str) -> Variable:
262
+ return self.get_variable(a, b, role, VariableType.SEMI_CONTINUOUS)
263
+
264
+ def __get_variable_9(
265
+ self, a: Individual, b: Individual, role: str, v_type: VariableType
266
+ ) -> Variable:
267
+ return self.get_variable(str(a), str(b), role, v_type)
268
+
269
+ def __get_variable_10(
270
+ self, a: str, b: str, role: str, v_type: VariableType
271
+ ) -> Variable:
272
+ var_name: str = f"({a},{b}):{role}"
273
+ var: Variable = self.get_variable(var_name)
274
+ if role in self.crisp_roles:
275
+ var.set_binary_variable()
276
+ if self.show_vars.show_abstract_role_fillers(
277
+ role, a
278
+ ) or self.show_vars.show_concrete_fillers(role, a):
279
+ self.show_vars.add_variable(var, var_name)
280
+ var.set_type(v_type)
281
+ return var
282
+
283
+ def __get_variable_11(self, ind: CreatedIndividual) -> Variable:
284
+ return self.get_variable(ind, VariableType.CONTINUOUS)
285
+
286
+ def __get_variable_12(self, ind: CreatedIndividual, v_type: VariableType) -> None:
287
+ if ind.get_parent() is None:
288
+ parent_name: str = "unknown_parent"
289
+ else:
290
+ parent_name: str = str(ind.get_parent())
291
+ feture_name: str = ind.get_role_name()
292
+ if feture_name is None:
293
+ feture_name = "unknown_feature"
294
+ name: str = f"{feture_name}({parent_name})"
295
+ if name == "unknown_feature(unknown_parent)":
296
+ name = str(ind)
297
+
298
+ if name in self.number_of_variables:
299
+ x_c: Variable = self.get_variable(name)
300
+ else:
301
+ x_c: Variable = self.get_variable(name)
302
+ if self.show_vars.show_concrete_fillers(feture_name, parent_name):
303
+ self.show_vars.add_variable(x_c, name)
304
+ x_c.set_type(v_type)
305
+ return x_c
306
+
307
+ @typing.overload
308
+ def has_variable(self, name: str) -> bool: ...
309
+
310
+ @typing.overload
311
+ def has_variable(self, ass: Assertion) -> bool: ...
312
+
313
+ def has_variable(self, *args) -> bool:
314
+ assert len(args) == 1
315
+ if isinstance(args[0], str):
316
+ return self.__has_variable_1(*args)
317
+ elif isinstance(args[0], Assertion):
318
+ return self.__has_variable_2(*args)
319
+ else:
320
+ raise ValueError
321
+
322
+ def __has_variable_1(self, name: str) -> bool:
323
+ return name in self.number_of_variables
324
+
325
+ def __has_variable_2(self, ass: Assertion) -> bool:
326
+ return self.has_variable(ass.get_name_without_degree())
327
+
328
+ @typing.overload
329
+ def get_nominal_variable(self, i1: str) -> Variable: ...
330
+
331
+ @typing.overload
332
+ def get_nominal_variable(self, i1: str, i2: str) -> Variable: ...
333
+
334
+ def get_nominal_variable(self, *args) -> Variable:
335
+ assert len(args) in [1, 2]
336
+ assert isinstance(args[0], str)
337
+ if len(args) == 1:
338
+ return self.__get_nominal_variable_1(*args)
339
+ else:
340
+ assert isinstance(args[1], str)
341
+ return self.__get_nominal_variable_2(*args)
342
+
343
+ def __get_nominal_variable_1(self, i1: str) -> Variable:
344
+ return self.get_nominal_variable(i1, i1)
345
+
346
+ def __get_nominal_variable_2(self, i1: str, i2: str) -> Variable:
347
+ var_name = f"{i1}:{{ {i2} }}"
348
+ v: Variable = self.get_variable(var_name)
349
+ v.set_type(VariableType.BINARY)
350
+ return v
351
+
352
+ def exists_nominal_variable(self, i: str) -> bool:
353
+ var_name: str = f"{i}:{{ {i} }}"
354
+ return var_name in list(map(str, self.variables))
355
+
356
+ def get_negated_nominal_variable(self, i1: str, i2: str) -> Variable:
357
+ var_name: str = f"{i1}: not {{ {i2} }}"
358
+ flag: bool = var_name in list(map(str, self.variables))
359
+ v: Variable = self.get_variable(var_name)
360
+ if not flag:
361
+ v.set_type(VariableType.BINARY)
362
+ not_v: Variable = self.get_nominal_variable(i1, i2)
363
+ self.add_new_constraint(
364
+ Expression(1.0, Term(-1.0, v), Term(-1.0, not_v)), InequalityType.EQUAL
365
+ )
366
+ return v
367
+
368
+ @typing.overload
369
+ def add_new_constraint(
370
+ self, expr: Expression, constraint_type: InequalityType
371
+ ) -> None: ...
372
+
373
+ @typing.overload
374
+ def add_new_constraint(self, x: Variable, n: float) -> None: ...
375
+
376
+ @typing.overload
377
+ def add_new_constraint(self, ass: Assertion, n: float) -> None: ...
378
+
379
+ @typing.overload
380
+ def add_new_constraint(self, x: Variable, d: Degree) -> None: ...
381
+
382
+ @typing.overload
383
+ def add_new_constraint(self, ass: Assertion) -> None: ...
384
+
385
+ @typing.overload
386
+ def add_new_constraint(
387
+ self, expr: Expression, constraint_type: InequalityType, degree: Degree
388
+ ) -> None: ...
389
+
390
+ @typing.overload
391
+ def add_new_constraint(
392
+ self, expr: Expression, constraint_type: InequalityType, n: float
393
+ ) -> None: ...
394
+
395
+ def add_new_constraint(self, *args) -> None:
396
+ assert len(args) in [1, 2, 3]
397
+ if len(args) == 1:
398
+ assert isinstance(args[0], Assertion)
399
+ self.__add_new_constraint_5(*args)
400
+ elif len(args) == 2:
401
+ if isinstance(args[0], Expression) and isinstance(args[1], InequalityType):
402
+ self.__add_new_constraint_1(*args)
403
+ elif isinstance(args[0], Variable) and isinstance(
404
+ args[1], constants.NUMBER
405
+ ):
406
+ self.__add_new_constraint_2(*args)
407
+ elif isinstance(args[0], Assertion) and isinstance(
408
+ args[1], constants.NUMBER
409
+ ):
410
+ self.__add_new_constraint_3(*args)
411
+ elif isinstance(args[0], Variable) and isinstance(args[1], Degree):
412
+ self.__add_new_constraint_4(*args)
413
+ else:
414
+ raise ValueError
415
+ elif len(args) == 3:
416
+ if (
417
+ isinstance(args[0], Expression)
418
+ and isinstance(args[1], InequalityType)
419
+ and isinstance(args[2], Degree)
420
+ ):
421
+ self.__add_new_constraint_6(*args)
422
+ elif (
423
+ isinstance(args[0], Expression)
424
+ and isinstance(args[1], InequalityType)
425
+ and isinstance(args[2], constants.NUMBER)
426
+ ):
427
+ self.__add_new_constraint_7(*args)
428
+ else:
429
+ raise ValueError
430
+ else:
431
+ raise ValueError
432
+
433
+ def __add_new_constraint_1(
434
+ self, expr: Expression, constraint_type: InequalityType
435
+ ) -> None:
436
+ self.constraints.append(Inequation(expr, constraint_type))
437
+
438
+ def __add_new_constraint_2(self, x: Variable, n: float) -> None:
439
+ self.add_new_constraint(
440
+ Expression(Term(1.0, x)),
441
+ InequalityType.GREATER_THAN,
442
+ DegreeNumeric.get_degree(n),
443
+ )
444
+
445
+ def __add_new_constraint_3(self, ass: Assertion, n: float) -> None:
446
+ self.add_new_constraint(self.get_variable(ass), n)
447
+
448
+ def __add_new_constraint_4(self, x: Variable, d: Degree) -> None:
449
+ self.add_new_constraint(
450
+ Expression(Term(1.0, x)), InequalityType.GREATER_THAN, d
451
+ )
452
+
453
+ def __add_new_constraint_5(self, ass: Assertion) -> None:
454
+ x_ass: Variable = self.get_variable(ass)
455
+ ass_name: str = str(x_ass)
456
+ deg: Degree = ass.get_lower_limit()
457
+ if isinstance(deg, DegreeVariable):
458
+ deg_name: str = str(typing.cast(DegreeVariable, deg).get_variable())
459
+ if ass_name == deg_name:
460
+ return
461
+ self.add_new_constraint(x_ass, deg)
462
+
463
+ def __add_new_constraint_6(
464
+ self, expr: Expression, constraint_type: InequalityType, degree: Degree
465
+ ) -> None:
466
+ self.constraints.append(
467
+ degree.create_inequality_with_degree_rhs(expr, constraint_type)
468
+ )
469
+
470
+ def __add_new_constraint_7(
471
+ self, expr: Expression, constraint_type: InequalityType, n: float
472
+ ) -> None:
473
+ self.add_new_constraint(expr, constraint_type, DegreeNumeric.get_degree(n))
474
+
475
+ def add_equality(self, var1: Variable, var2: Variable) -> None:
476
+ self.add_new_constraint(
477
+ Expression(Term(1.0, var1), Term(-1.0, var2)), InequalityType.EQUAL
478
+ )
479
+
480
+ def add_string_feature(self, role: str) -> None:
481
+ self.string_features.add(role)
482
+
483
+ def add_string_value(self, value: str, int_value: int) -> None:
484
+ self.string_values[int_value] = value
485
+
486
+ def change_variable_names(
487
+ self, old_name: str, new_name: str, old_is_created_individual: bool
488
+ ) -> None:
489
+ old_values: list[str] = [f"{old_name},", f",{old_name}", f"{old_name}:"]
490
+ new_values: list[str] = [f"{new_name},", f",{new_name}", f"{new_name}:"]
491
+ to_process: list[Variable] = copy.deepcopy(self.variables)
492
+ for v1 in to_process:
493
+ name: str = str(v1)
494
+ for old_value, new_value in zip(old_values, new_values):
495
+ if name not in old_value:
496
+ continue
497
+ name2: str = name.replace(old_value, new_value, 1)
498
+ v2: Variable = self.get_variable(name2)
499
+ if self.check_if_replacement_is_needed(v1, old_value, v2, new_value):
500
+ if old_is_created_individual:
501
+ self.add_equality(v1, v2)
502
+ else:
503
+ a_is_b: Variable = self.get_nominal_variable(new_name, old_name)
504
+ self.add_new_constraint(
505
+ Expression(
506
+ 1.0, Term(-1.0, a_is_b), Term(1.0, v1), Term(-1.0, v2)
507
+ ),
508
+ InequalityType.GREATER_THAN,
509
+ )
510
+
511
+ def check_if_replacement_is_needed(
512
+ self, v1: Variable, s1: str, v2: Variable, s2: str
513
+ ) -> bool:
514
+ name1: str = str(v1)
515
+ begin1: int = name1.index(s1)
516
+ name2: str = str(v2)
517
+ begin2: int = name2.index(s2)
518
+ if begin1 != begin2:
519
+ return False
520
+ return (
521
+ name1[:begin1] == name2[:begin2]
522
+ and name1[begin1 + len(s1) :] == name2[begin2 + len(s2) :]
523
+ )
524
+
525
+ @typing.overload
526
+ def get_ordered_permutation(self, x: list[Variable]) -> list[Variable]: ...
527
+
528
+ @typing.overload
529
+ def get_ordered_permutation(
530
+ self, x: list[Variable], z: list[list[Variable]]
531
+ ) -> list[Variable]: ...
532
+
533
+ def get_ordered_permutation(self, *args) -> list[Variable]:
534
+ assert len(args) in [1, 2]
535
+ assert isinstance(args[0], list) and all(
536
+ isinstance(a, Variable) for a in args[0]
537
+ )
538
+ if len(args) == 1:
539
+ return self.__get_ordered_permutation_1(*args)
540
+ elif len(args) == 2:
541
+ assert isinstance(args[1], list) and all(
542
+ isinstance(a, Variable) for a in args[1]
543
+ )
544
+ return self.__get_ordered_permutation_2(*args)
545
+ else:
546
+ raise ValueError
547
+
548
+ def __get_ordered_permutation_1(self, x: list[Variable]) -> list[Variable]:
549
+ n: int = len(x)
550
+ z: list[list[Variable]] = [
551
+ [self.get_new_variable(VariableType.BINARY) for _ in range(n)]
552
+ for _ in range(n)
553
+ ]
554
+ return self.get_ordered_permutation(x, z)
555
+
556
+ def __get_ordered_permutation_2(
557
+ self, x: list[Variable], z: list[list[Variable]]
558
+ ) -> list[Variable]:
559
+ n: int = len(x)
560
+ y: list[Variable] = [
561
+ self.get_new_variable(VariableType.SEMI_CONTINUOUS) for _ in range(n)
562
+ ]
563
+ for i in range(n - 1):
564
+ self.add_new_constraint(
565
+ Expression(Term(1.0, y[i]), Term(-1.0, y[i + 1])),
566
+ InequalityType.GREATER_THAN,
567
+ )
568
+ for i in range(n):
569
+ for j in range(n):
570
+ self.add_new_constraint(
571
+ Expression(Term(1.0, x[j]), Term(-1.0, y[i]), Term(1.0, z[i][j])),
572
+ InequalityType.GREATER_THAN,
573
+ )
574
+ for i in range(n):
575
+ for j in range(n):
576
+ self.add_new_constraint(
577
+ Expression(Term(1.0, x[j]), Term(-1.0, y[i]), Term(-1.0, z[i][j])),
578
+ InequalityType.LESS_THAN,
579
+ )
580
+ for i in range(n):
581
+ exp: Expression = Expression(1.0 - n)
582
+ for j in range(n):
583
+ exp.add_term(Term(1.0, z[i][j]))
584
+ self.add_new_constraint(exp, InequalityType.EQUAL)
585
+
586
+ for i in range(n):
587
+ exp: Expression = Expression(1.0 - n)
588
+ for j in range(n):
589
+ exp.add_term(Term(1.0, z[j][i]))
590
+ self.add_new_constraint(exp, InequalityType.EQUAL)
591
+ return y
592
+
593
+ def solve_gurobi(self, objective: Expression) -> typing.Optional[Solution]:
594
+ try:
595
+ Util.debug("Running MILP solver: Gurobi")
596
+ Util.debug(f"Objective function -> {objective}")
597
+
598
+ num_binary_vars: int = 0
599
+ num_free_vars: int = 0
600
+ num_integer_vars: int = 0
601
+ num_up_vars: int = 0
602
+ size: int = len(self.variables)
603
+ objective_value: list[float] = [0.0] * size
604
+
605
+ if objective is not None:
606
+ for term in objective.get_terms():
607
+ index = self.variables.index(term.get_var())
608
+ objective_value[index] += term.get_coeff()
609
+
610
+ env = gp.Env(empty=True)
611
+ if not ConfigReader.DEBUG_PRINT:
612
+ env.setParam("OutputFlag", 0)
613
+ env.setParam("IntFeasTol", 1e-9)
614
+ env.setParam("BarConvTol", 0)
615
+ env.start()
616
+
617
+ model = gp.Model("model", env=env)
618
+ vars_gurobi: list[gp.Var] = []
619
+ show_variable: list[bool] = [False] * size
620
+
621
+ my_vars: list[Variable] = self.show_vars.get_variables()
622
+
623
+ for i in range(size):
624
+ v: Variable = self.variables[i]
625
+ v_type: VariableType = v.get_type()
626
+ ov: float = objective_value[i]
627
+
628
+ Util.debug(
629
+ (
630
+ f"Variable -- "
631
+ f"[{v.get_lower_bound()}, {v.get_upper_bound()}] - "
632
+ f"Obj value = {ov} - "
633
+ f"Var type = {v_type.name} -- "
634
+ f"Var = {v}"
635
+ )
636
+ )
637
+
638
+ vars_gurobi.append(
639
+ model.addVar(
640
+ lb=v.get_lower_bound(),
641
+ ub=v.get_upper_bound(),
642
+ obj=ov,
643
+ vtype=v_type.name,
644
+ name=str(v),
645
+ )
646
+ )
647
+
648
+ if v in my_vars:
649
+ show_variable[i] = True
650
+
651
+ if v_type == VariableType.BINARY:
652
+ num_binary_vars += 1
653
+ elif v_type == VariableType.CONTINUOUS:
654
+ num_free_vars += 1
655
+ elif v_type == VariableType.INTEGER:
656
+ num_integer_vars += 1
657
+ elif v_type == VariableType.SEMI_CONTINUOUS:
658
+ num_up_vars += 1
659
+
660
+ model.update()
661
+
662
+ Util.debug(f"# constraints -> {len(self.constraints)}")
663
+ constraint_name: str = "constraint"
664
+ for i, constraint in enumerate(self.constraints):
665
+ curr_name: str = f"{constraint_name}_{i + 1}"
666
+ expr: gp.LinExpr = gp.LinExpr()
667
+ for term in constraint.get_terms():
668
+ index: int = self.variables.index(term.get_var())
669
+ v: gp.Var = vars_gurobi[index]
670
+ c: float = term.get_coeff()
671
+ if c == 0:
672
+ continue
673
+ expr.add(v, c)
674
+
675
+ if expr.size() == 0:
676
+ continue
677
+
678
+ if constraint.get_type() == InequalityType.EQUAL:
679
+ gp_constraint: gp.Constr = expr == constraint.get_constant()
680
+ elif constraint.get_type() == InequalityType.LESS_THAN:
681
+ gp_constraint: gp.Constr = expr <= constraint.get_constant()
682
+ elif constraint.get_type() == InequalityType.GREATER_THAN:
683
+ gp_constraint: gp.Constr = expr >= constraint.get_constant()
684
+
685
+ model.addConstr(gp_constraint, curr_name)
686
+ Util.debug(f"{curr_name}: {gp_constraint}")
687
+
688
+ model.update()
689
+ model.optimize()
690
+
691
+ model.write(os.path.join(constants.RESULTS_PATH, "model.lp"))
692
+ model.write(os.path.join(constants.RESULTS_PATH, "solution.json"))
693
+
694
+ Util.debug(f"Model:")
695
+ sol: Solution = None
696
+ if model.Status == GRB.INFEASIBLE and ConfigReader.RELAX_MILP:
697
+ self.__handle_model_infeasibility(model)
698
+
699
+ if model.Status == GRB.INFEASIBLE:
700
+ sol = Solution(False)
701
+ else:
702
+ for i in range(size):
703
+ if ConfigReader.DEBUG_PRINT or show_variable[i]:
704
+ name: str = vars_gurobi[i].VarName
705
+ value: float = round(vars_gurobi[i].X, 6)
706
+ if self.PRINT_VARIABLES:
707
+ Util.debug(f"{name} = {value}")
708
+ if self.PRINT_LABELS:
709
+ self.print_instance_of_labels(name, value)
710
+ result: float = Util.round(abs(model.ObjVal))
711
+ sol = Solution(result)
712
+
713
+ model.printQuality()
714
+ model.printStats()
715
+
716
+ Util.debug(
717
+ f"{constants.STAR_SEPARATOR}Statistics{constants.STAR_SEPARATOR}"
718
+ )
719
+ Util.debug("MILP problem:")
720
+ Util.debug(f"\t\tSemi continuous variables: {num_up_vars}")
721
+ Util.debug(f"\t\tBinary variables: {num_binary_vars}")
722
+ Util.debug(f"\t\tContinuous variables: {num_free_vars}")
723
+ Util.debug(f"\t\tInteger variables: {num_integer_vars}")
724
+ Util.debug(f"\t\tTotal variables: {len(self.variables)}")
725
+ Util.debug(f"\t\tConstraints: {len(self.constraints)}")
726
+ return sol
727
+ except gp.GurobiError as e:
728
+ Util.error(f"Error code: {e.errno}. {e.message}")
729
+ return None
730
+
731
+ def __handle_model_infeasibility(self, model: gp.Model) -> None:
732
+ model.computeIIS()
733
+ # Print out the IIS constraints and variables
734
+ Util.debug("The following constraints and variables are in the IIS:")
735
+ Util.debug("Constraints:")
736
+ for c in model.getConstrs():
737
+ assert isinstance(c, gp.Constr)
738
+ if c.IISConstr:
739
+ Util.debug(f"\t\t{c.ConstrName}: {model.getRow(c)} {c.Sense} {c.RHS}")
740
+
741
+ Util.debug("Variables:")
742
+ for v in model.getVars():
743
+ if v.IISLB:
744
+ Util.debug(f"\t\t{v.VarName} ≥ {v.LB}")
745
+ if v.IISUB:
746
+ Util.debug(f"\t\t{v.VarName} ≤ {v.UB}")
747
+
748
+ Util.debug("Relaxing the variable bounds:")
749
+ # relaxing only variable bounds
750
+ model.feasRelaxS(0, False, True, False)
751
+ # for relaxing variable bounds and constraint bounds use
752
+ # model.feasRelaxS(0, False, True, True)
753
+ model.optimize()
754
+
755
+ def add_crisp_concept(self, concept_name: str) -> None:
756
+ self.crisp_concepts.add(concept_name)
757
+
758
+ def add_crisp_role(self, role_name: str) -> None:
759
+ self.crisp_roles.add(role_name)
760
+
761
+ def is_crisp_concept(self, concept_name: str) -> bool:
762
+ return concept_name in self.crisp_concepts
763
+
764
+ def is_crisp_role(self, role_name: str) -> bool:
765
+ return role_name in self.crisp_roles
766
+
767
+ def set_binary_variables(self) -> None:
768
+ for v in self.variables:
769
+ if v.get_datatype_filler_type() or v.get_type() in (
770
+ VariableType.CONTINUOUS,
771
+ VariableType.INTEGER,
772
+ ):
773
+ continue
774
+ v.set_binary_variable()
775
+
776
+ def get_name_for_integer(self, i: int) -> typing.Optional[str]:
777
+ for name, i2 in self.number_of_variables.items():
778
+ if i == i2:
779
+ return name
780
+ return None
781
+
782
+ def get_number_for_assertion(self, ass: Assertion) -> int:
783
+ return self.number_of_variables.get(str(self.get_variable(ass)))
784
+
785
+ def add_contradiction(self) -> None:
786
+ self.constraints.clear()
787
+ self.add_new_constraint(Expression(1.0), InequalityType.EQUAL)