fuzzy-dl-owl2 1.0.6__py3-none-any.whl → 1.0.8__py3-none-any.whl

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