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
@@ -10,6 +10,7 @@ from .exception import *
10
10
  from .feature_function import FeatureFunction
11
11
  from .general_concept_inclusion import GeneralConceptInclusion
12
12
  from .individual import *
13
+ from .classification_node import ClassificationNode
13
14
  from .knowledge_base import KnowledgeBase
14
15
  from .label import Label
15
16
  from .modifier import *
@@ -20,4 +21,4 @@ from .range_axiom import RangeAxiom
20
21
  from .relation import Relation
21
22
  from .restriction import *
22
23
  from .role_parent_with_degree import RoleParentWithDegree
23
- from .fuzzydl_to_owl2 import FuzzydlToOwl2
24
+ from .fuzzydl_to_owl2 import FuzzydlToOwl2
@@ -16,6 +16,7 @@ class Assertion:
16
16
  def __init__(self, ind: Individual, c: Concept, d: Degree) -> None:
17
17
  self.individual: Individual = ind
18
18
  self.concept: Concept = c
19
+ # Lower bound degree
19
20
  self.degree: Degree = d
20
21
 
21
22
  def clone(self) -> typing.Self:
@@ -6,7 +6,9 @@ from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
6
6
 
7
7
  class AtomicAssertion:
8
8
  def __init__(self, c: Concept, degree: Degree) -> None:
9
+ # Atomic concept
9
10
  self.c: Concept = c
11
+ # Lower bound degree
10
12
  self.degree: Degree = degree
11
13
 
12
14
  def get_concept_name(self) -> str:
@@ -0,0 +1,64 @@
1
+ import typing
2
+
3
+
4
+ class ClassificationNode:
5
+ EQUIVALENT_NAMES: set[str] = set()
6
+ INPUT_EDGES: dict[typing.Self, float] = dict()
7
+ OUTPUT_EDGES: dict[typing.Self, float] = dict()
8
+
9
+ def __init__(self, name: str) -> None:
10
+ ClassificationNode.EQUIVALENT_NAMES.add(name)
11
+
12
+ def is_thing(self) -> bool:
13
+ return self.has_name("*top*")
14
+
15
+ def is_nothing(self) -> bool:
16
+ return self.has_name("*bottom*")
17
+
18
+ def add_input_edge(self, node: typing.Self, n: float) -> None:
19
+ ClassificationNode.INPUT_EDGES[node] = n
20
+
21
+ def add_ouput_edge(self, node: typing.Self, n: float) -> None:
22
+ ClassificationNode.OUTPUT_EDGES[node] = n
23
+
24
+ def remove_input_edge(self, node: typing.Self, n: float) -> None:
25
+ value: typing.Optional[float] = ClassificationNode.INPUT_EDGES.get(node)
26
+ if value is not None and value <= n:
27
+ del ClassificationNode.INPUT_EDGES[node]
28
+
29
+ def remove_ouput_edge(self, node: typing.Self, n: float) -> None:
30
+ value: typing.Optional[float] = ClassificationNode.OUTPUT_EDGES.get(node)
31
+ if value is not None and value <= n:
32
+ del ClassificationNode.OUTPUT_EDGES[node]
33
+
34
+ def has_name(self, name: str) -> bool:
35
+ for s in ClassificationNode.EQUIVALENT_NAMES:
36
+ if s == name:
37
+ return True
38
+ return False
39
+
40
+ def add_label(self, c: str) -> None:
41
+ ClassificationNode.EQUIVALENT_NAMES.add(c)
42
+
43
+ def get_output_edges() -> dict[typing.Self, float]:
44
+ return ClassificationNode.OUTPUT_EDGES
45
+
46
+ def get_immediate_successors() -> set[typing.Self]:
47
+ return set(ClassificationNode.INPUT_EDGES.keys())
48
+
49
+ def get_immediate_predecessors() -> set[typing.Self]:
50
+ return set(ClassificationNode.OUTPUT_EDGES.keys())
51
+
52
+ def get_full_name(self) -> str:
53
+ if len(ClassificationNode.EQUIVALENT_NAMES) == 1:
54
+ return str(self)
55
+ return f"{{{ ' '.join(name for name in ClassificationNode.EQUIVALENT_NAMES) }}}"
56
+
57
+ def __hash__(self) -> int:
58
+ return hash(str(self))
59
+
60
+ def __repr__(self) -> str:
61
+ return str(self)
62
+
63
+ def __str__(self) -> str:
64
+ return list(ClassificationNode.EQUIVALENT_NAMES)[0]
@@ -11,3 +11,5 @@ from .weighted_max_concept import WeightedMaxConcept
11
11
  from .weighted_min_concept import WeightedMinConcept
12
12
  from .weighted_sum_concept import WeightedSumConcept
13
13
  from .weighted_sum_zero_concept import WeightedSumZeroConcept
14
+ from .sigma_concept import SigmaConcept
15
+ from .sigma_count import SigmaCount
@@ -44,7 +44,7 @@ class AtomicConcept(Concept):
44
44
  return AtomicConcept(self.name)
45
45
 
46
46
  def compute_atomic_concepts(self) -> set[typing.Self]:
47
- return [self]
47
+ return set([self])
48
48
 
49
49
  def get_roles(self) -> set[str]:
50
50
  return set()
@@ -12,6 +12,10 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
12
12
 
13
13
 
14
14
  class ChoquetIntegral(Concept, HasWeightedConceptsInterface):
15
+ """
16
+ Choquet integral concept.
17
+ """
18
+
15
19
  def __init__(self, weights: list[float], concepts: list[Concept]) -> None:
16
20
  Concept.__init__(self, ConceptType.CHOQUET_INTEGRAL)
17
21
  HasWeightedConceptsInterface.__init__(self, weights, concepts)
@@ -22,6 +26,8 @@ class ChoquetIntegral(Concept, HasWeightedConceptsInterface):
22
26
  "Error: The number of weights and the number of concepts should be the same"
23
27
  )
24
28
  self.name: str = str(self)
29
+ else:
30
+ self.weights = list()
25
31
 
26
32
  def clone(self) -> typing.Self:
27
33
  return ChoquetIntegral(self.weights[:], [c for c in self.concepts])
@@ -116,6 +116,9 @@ class Thing(ABC):
116
116
  def get_atomic_concepts(self) -> set[typing.Self]:
117
117
  return self.compute_atomic_concepts()
118
118
 
119
+ def get_atomic_concepts_names(self) -> set[str]:
120
+ return set([str(concept) for concept in self.compute_atomic_concepts()])
121
+
119
122
  @abstractmethod
120
123
  def get_roles(self) -> set[str]:
121
124
  pass
@@ -163,14 +166,19 @@ class Thing(ABC):
163
166
 
164
167
 
165
168
  class Concept(Thing):
169
+ # Used to create new concepts
166
170
  SPECIAL_STRING = "@"
171
+ # Default prefix for new individual names.
167
172
  DEFAULT_NAME = f"Concept{SPECIAL_STRING}"
173
+ # Number of new concepts
168
174
  num_new_concepts = 1
169
175
 
170
176
  def __init__(
171
177
  self, c_type: ConceptType = ConceptType.ATOMIC, name: str = ""
172
178
  ) -> None:
179
+ # Type of the concept
173
180
  self._type: ConceptType = c_type
181
+ # Name of the concept
174
182
  self._name: str = name
175
183
 
176
184
  @property
@@ -9,6 +9,7 @@ from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
9
9
 
10
10
 
11
11
  class CrispConcreteConcept(FuzzyConcreteConcept):
12
+ """Concrete concept defined with a crisp interval."""
12
13
 
13
14
  def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
14
15
  super().__init__(name)
@@ -12,6 +12,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
12
12
 
13
13
 
14
14
  class FuzzyConcreteConcept(Concept, ABC):
15
+ """Fuzzy concrete concept defined with an explicit membership function."""
15
16
 
16
17
  def __init__(self, name: str) -> None:
17
18
  super().__init__(ConceptType.CONCRETE, name)
@@ -12,7 +12,11 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
12
12
 
13
13
 
14
14
  class TriangularFuzzyNumber(TriangularConcreteConcept):
15
+ """Fuzzy number defined with a triangular function."""
16
+
17
+ # Lower bound of the range of the fuzzy numbers.
15
18
  K1: float = float("-inf")
19
+ # Upper bound of the range of the fuzzy numbers.
16
20
  K2: float = float("inf")
17
21
 
18
22
  @typing.overload
@@ -41,18 +45,24 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
41
45
 
42
46
  @staticmethod
43
47
  def add(t1: typing.Self, t2: typing.Self) -> typing.Self:
48
+ """
49
+ Adds two triangular fuzzy numbers.
50
+ """
44
51
  return t1 + t2
45
52
 
46
53
  @staticmethod
47
54
  def minus(t1: typing.Self, t2: typing.Self) -> typing.Self:
55
+ """Subtracts two triangular fuzzy numbers."""
48
56
  return t1 - t2
49
57
 
50
58
  @staticmethod
51
59
  def times(t1: typing.Self, t2: typing.Self) -> typing.Self:
60
+ """Multiplies two triangular fuzzy numbers."""
52
61
  return t1 * t2
53
62
 
54
63
  @staticmethod
55
64
  def divided_by(t1: typing.Self, t2: typing.Self) -> typing.Self:
65
+ """Divides two triangular fuzzy numbers."""
56
66
  return t1 / t2
57
67
 
58
68
  @staticmethod
@@ -62,6 +72,7 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
62
72
 
63
73
  @staticmethod
64
74
  def has_defined_range() -> bool:
75
+ """Checks if the range of the fuzzy numbers has been defined."""
65
76
  return TriangularFuzzyNumber.K1 != float("-inf")
66
77
 
67
78
  def clone(self) -> typing.Self:
@@ -71,6 +82,7 @@ class TriangularFuzzyNumber(TriangularConcreteConcept):
71
82
  return True
72
83
 
73
84
  def get_best_non_fuzzy_performance(self) -> float:
85
+ """Gets the Best Non fuzzy Performance (BNP) of the fuzzy number."""
74
86
  return Util.round((self.a + self.b + self.c) / 3.0)
75
87
 
76
88
  def is_number(self) -> bool:
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class LeftConcreteConcept(FuzzyConcreteConcept):
13
+ """
14
+ Fuzzy concrete concept defined with a left shoulder function
15
+ """
13
16
 
14
17
  def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
15
18
  super().__init__(name)
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class LinearConcreteConcept(FuzzyConcreteConcept):
13
+ """
14
+ Fuzzy concrete concept defined with a left shoulder function
15
+ """
13
16
 
14
17
  def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
15
18
  super().__init__(name)
@@ -10,6 +10,10 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
10
10
 
11
11
 
12
12
  class ModifiedConcreteConcept(FuzzyConcreteConcept):
13
+ """
14
+ Modified concrete concept.
15
+ """
16
+
13
17
  def __init__(self, name: str, modifier: Modifier, f: FuzzyConcreteConcept) -> None:
14
18
  super().__init__(name)
15
19
  self.k1: float = 0.0
@@ -11,6 +11,8 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
11
11
 
12
12
  class RightConcreteConcept(FuzzyConcreteConcept):
13
13
 
14
+ """Fuzzy concrete concept defined with a right shoulder function."""
15
+
14
16
  def __init__(self, name: str, k1: float, k2: float, a: float, b: float) -> None:
15
17
  super().__init__(name)
16
18
  if a > b:
@@ -10,6 +10,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class TrapezoidalConcreteConcept(FuzzyConcreteConcept):
13
+ """Fuzzy concrete concept defined with a trapezoidal function."""
13
14
 
14
15
  def __init__(
15
16
  self, name: str, k1: float, k2: float, a: float, b: float, c: float, d: float
@@ -12,6 +12,8 @@ from fuzzy_dl_owl2.fuzzydl.exception.fuzzy_ontology_exception import (
12
12
 
13
13
 
14
14
  class TriangularConcreteConcept(FuzzyConcreteConcept):
15
+ """Fuzzy concrete concept defined with a triangular function."""
16
+
15
17
  def __init__(
16
18
  self, name: str, k1: float, k2: float, a: float, b: float, c: float
17
19
  ) -> None:
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
9
9
 
10
10
 
11
11
  class LinearlyModifiedConcept(ModifiedConcept):
12
+ """
13
+ Fuzzy concept modified with a linear modifier
14
+ """
12
15
 
13
16
  def __init__(self, c: Concept, mod: Modifier) -> None:
14
17
  super().__init__(c, mod)
@@ -13,6 +13,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
13
13
 
14
14
 
15
15
  class ModifiedConcept(Concept, HasConceptInterface, ABC):
16
+ """
17
+ Modified fuzzy concept.
18
+ """
16
19
 
17
20
  def __init__(self, c: Concept, mod: Modifier) -> None:
18
21
  Concept.__init__(self, ConceptType.MODIFIED)
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
9
9
 
10
10
 
11
11
  class TriangularlyModifiedConcept(ModifiedConcept):
12
+
13
+ """Fuzzy concept modified with a triangular modifier."""
14
+
12
15
  def __init__(self, c: Concept, mod: Modifier) -> None:
13
16
  super().__init__(c, mod)
14
17
 
@@ -9,6 +9,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
9
9
 
10
10
 
11
11
  class NegatedNominal(Concept):
12
+ """
13
+ Negated nominal concept. Only used in range restrictions for the moment.
14
+ """
12
15
 
13
16
  def __init__(self, ind_name: str) -> None:
14
17
  super().__init__(ConceptType.ATOMIC)
@@ -12,6 +12,10 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType, FuzzyLogic
12
12
 
13
13
 
14
14
  class OperatorConcept(Concept, HasConceptsInterface):
15
+ """
16
+ Defines a logic operator concept defined as AND, OR or NOT of concepts.
17
+ """
18
+
15
19
  AND_OPERATORS: list[ConceptType] = [
16
20
  ConceptType.AND,
17
21
  ConceptType.GOEDEL_AND,
@@ -262,6 +266,10 @@ class OperatorConcept(Concept, HasConceptsInterface):
262
266
  def is_not_zadeh_implies(op: Concept) -> bool:
263
267
  return OperatorConcept.is_not_type(op, ConceptType.ZADEH_IMPLIES)
264
268
 
269
+ @staticmethod
270
+ def is_not_sigma_concept(op: Concept) -> bool:
271
+ return OperatorConcept.is_not_type(op, ConceptType.SIGMA_CONCEPT)
272
+
265
273
  def is_concrete(self) -> bool:
266
274
  if OperatorConcept.is_not_concrete(self) or OperatorConcept.is_not_fuzzy_number(
267
275
  self
@@ -10,6 +10,10 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
10
10
 
11
11
 
12
12
  class QowaConcept(OwaConcept):
13
+ """
14
+ Quantified-guided OWA concept.
15
+ """
16
+
13
17
  def __init__(
14
18
  self, quantifier: FuzzyConcreteConcept, concepts: list[Concept]
15
19
  ) -> None:
@@ -10,6 +10,9 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class QsugenoIntegral(SugenoIntegral):
13
+ """
14
+ Quasi Sugeno integral concept.
15
+ """
13
16
 
14
17
  def __init__(self, weights: list[float], concepts: list[Concept]) -> None:
15
18
  super().__init__(weights, concepts)
@@ -0,0 +1,71 @@
1
+ import typing
2
+
3
+ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
4
+ from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import (
5
+ FuzzyConcreteConcept,
6
+ )
7
+ from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
8
+ from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
9
+ from fuzzy_dl_owl2.fuzzydl.util.constants import ConceptType
10
+
11
+
12
+ class SigmaConcept(Concept):
13
+ """Sigma-count concept."""
14
+
15
+ def __init__(
16
+ self,
17
+ concept: Concept,
18
+ role: str,
19
+ individuals: list[Individual],
20
+ concrete_concept: FuzzyConcreteConcept,
21
+ ) -> None:
22
+ super().__init__(ConceptType.SIGMA_CONCEPT, "")
23
+ self.concept: Concept = concept
24
+ self.role: str = role
25
+ self.individuals: list[Individual] = individuals
26
+ self.concrete_concept: FuzzyConcreteConcept = concrete_concept
27
+ self.name: str = self.compute_name()
28
+
29
+ def get_individuals(self) -> list[Individual]:
30
+ return self.individuals
31
+
32
+ def get_concept(self) -> Concept:
33
+ return self.concept
34
+
35
+ def get_role(self) -> str:
36
+ return self.role
37
+
38
+ def get_fuzzy_concept(self) -> FuzzyConcreteConcept:
39
+ return self.concrete_concept
40
+
41
+ def clone(self) -> typing.Self:
42
+ return SigmaConcept(
43
+ self.concept.clone(),
44
+ self.role,
45
+ [i.clone() for i in self.individuals],
46
+ self.concrete_concept.clone(),
47
+ )
48
+
49
+ def compute_atomic_concepts(self) -> set[Concept]:
50
+ return set()
51
+
52
+ def get_roles(self) -> set[str]:
53
+ return set()
54
+
55
+ def replace(self, a: Concept, c: Concept) -> Concept:
56
+ return self
57
+
58
+ def compute_name(self) -> str | None:
59
+ return f"(sigma-count {self.role} {self.concept} {{{' '.join(map(str, self.individuals))}}} {self.concrete_concept})"
60
+
61
+ def __neg__(self) -> Concept:
62
+ return OperatorConcept.not_(self)
63
+
64
+ def __and__(self, value: typing.Self) -> typing.Self:
65
+ return OperatorConcept.and_(self, value)
66
+
67
+ def __or__(self, value: typing.Self) -> typing.Self:
68
+ return OperatorConcept.or_(self, value)
69
+
70
+ def __hash__(self) -> int:
71
+ return hash(str(self))
@@ -0,0 +1,56 @@
1
+ import typing
2
+
3
+ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
4
+ from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
5
+ from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
6
+
7
+
8
+ class SigmaCount:
9
+ """Sigma-count pending tasks."""
10
+
11
+ def __init__(
12
+ self,
13
+ var: Variable,
14
+ ind: Individual,
15
+ inds: list[Individual],
16
+ role: str,
17
+ concept: Concept,
18
+ ) -> None:
19
+ self.variable: Variable = var
20
+ self.individual: Individual = ind
21
+ self.individuals: list[Individual] = inds
22
+ self.role: str = role
23
+ self.concept: Concept = concept
24
+
25
+ def clone(self) -> typing.Self:
26
+ return SigmaCount(
27
+ self.variable.clone(),
28
+ self.individual.clone(),
29
+ [i.clone() for i in self.individuals],
30
+ self.role,
31
+ self.concept.clone(),
32
+ )
33
+
34
+ def get_variable(self) -> Variable:
35
+ return self.variable
36
+
37
+ def get_individual(self) -> Individual:
38
+ return self.individual
39
+
40
+ def get_individuals(self) -> list[Individual]:
41
+ return self.individuals
42
+
43
+ def get_role(self) -> str:
44
+ return self.role
45
+
46
+ def get_concept(self) -> Concept:
47
+ return self.concept
48
+
49
+ def __hash__(self) -> int:
50
+ return hash(str(self))
51
+
52
+ def __repr__(self) -> str:
53
+ return str(self)
54
+
55
+ def __str__(self) -> str:
56
+ return f"sigma-count({self.variable}, {self.individual}, {self.individuals}, {self.role}, {self.concept})"
@@ -14,6 +14,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
14
14
 
15
15
 
16
16
  class SugenoIntegral(Concept, HasWeightedConceptsInterface):
17
+ """Sugeno integral concept."""
17
18
 
18
19
  @typing.overload
19
20
  def __init__(self) -> None: ...
@@ -48,6 +49,9 @@ class SugenoIntegral(Concept, HasWeightedConceptsInterface):
48
49
  "Error: The number of weights and the number of concepts should be the same"
49
50
  )
50
51
  self.name = self.compute_name()
52
+ else:
53
+ self.weights: list[float] = []
54
+
51
55
 
52
56
  def clone(self) -> typing.Self:
53
57
  return SugenoIntegral(self.weights[:], [c for c in self.concepts])
@@ -6,8 +6,13 @@ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
6
6
 
7
7
 
8
8
  class ConceptEquivalence:
9
+ """
10
+ Concept equivalence axiom
11
+ """
9
12
  def __init__(self, c1: Concept, c2: Concept) -> None:
13
+ # First concept
10
14
  self.c1: Concept = c1
15
+ # Second concept
11
16
  self.c2: Concept = c2
12
17
 
13
18
  def clone(self) -> typing.Self:
@@ -41,7 +41,9 @@ class ConcreteFeature:
41
41
 
42
42
  def __concrete_feature_init_1(self, name: str) -> None:
43
43
  self.name: str = name
44
+ # Lower bound for the range
44
45
  self.k1: typing.Optional[typing.Union[float, int]] = None
46
+ # Upper bound for the range
45
47
  self.k2: typing.Optional[typing.Union[float, int]] = None
46
48
  self.type: ConcreteFeatureType = ConcreteFeatureType.STRING
47
49
 
@@ -52,13 +54,17 @@ class ConcreteFeature:
52
54
 
53
55
  def __concrete_feature_init_3(self, name: str, k1: int, k2: int) -> None:
54
56
  self.__concrete_feature_init_1(name)
57
+ # Lower bound for the range
55
58
  self.k1: typing.Optional[typing.Union[float, int]] = k1
59
+ # Upper bound for the range
56
60
  self.k2: typing.Optional[typing.Union[float, int]] = k2
57
61
  self.type: ConcreteFeatureType = ConcreteFeatureType.INTEGER
58
62
 
59
63
  def __concrete_feature_init_4(self, name: str, k1: float, k2: float) -> None:
60
64
  self.__concrete_feature_init_1(name)
65
+ # Lower bound for the range
61
66
  self.k1: typing.Optional[typing.Union[float, int]] = k1
67
+ # Upper bound for the range
62
68
  self.k2: typing.Optional[typing.Union[float, int]] = k2
63
69
  self.type: ConcreteFeatureType = ConcreteFeatureType.REAL
64
70
 
@@ -2,6 +2,9 @@ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
2
2
 
3
3
 
4
4
  class DomainAxiom:
5
+ """
6
+ Role domain axiom
7
+ """
5
8
 
6
9
  def __init__(self, role: str, concept: Concept) -> None:
7
10
  self.role: str = role
@@ -12,6 +12,7 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import FeatureFunctionType
12
12
 
13
13
 
14
14
  class FeatureFunction:
15
+ """Function involving several features."""
15
16
 
16
17
  @typing.overload
17
18
  def __init__(self, feature: typing.Self) -> None: ...
@@ -105,6 +106,7 @@ class FeatureFunction:
105
106
  return self.n
106
107
 
107
108
  def get_features(self) -> set[str]:
109
+ """Gets an array of features that take part in the function."""
108
110
  features: set[str] = set()
109
111
  if self.type == FeatureFunctionType.ATOMIC:
110
112
  features.add(self.feature)
@@ -121,27 +123,34 @@ class FeatureFunction:
121
123
  def to_expression(
122
124
  self, a: Individual, milp: MILPHelper
123
125
  ) -> typing.Optional[Expression]:
126
+ """Gets an array of features that take part in the function."""
124
127
  if self.type == FeatureFunctionType.ATOMIC:
128
+ # Get the filler "b" for feature(a)
125
129
  rel_set: list[Relation] = a.role_relations.get(self.feature)
130
+ assert len(rel_set) > 0
126
131
  b: CreatedIndividual = typing.cast(
127
132
  CreatedIndividual, rel_set[0].get_object_individual()
128
133
  )
134
+ # Get the variable xB
129
135
  x_b: Variable = milp.get_variable(b)
130
136
  return Expression(Term(1.0, x_b))
131
137
  elif self.type == FeatureFunctionType.NUMBER:
132
138
  return Expression(self.n)
133
139
  elif self.type == FeatureFunctionType.PRODUCT:
140
+ assert len(self.f) == 1
134
141
  ex: Expression = self.f[0].to_expression(a, milp)
135
- return Expression.multiply_constant(ex, self.n)
142
+ return ex * self.n
136
143
  elif self.type == FeatureFunctionType.SUBTRACTION:
144
+ assert len(self.f) == 2
137
145
  ex1: Expression = self.f[0].to_expression(a, milp)
138
146
  ex2: Expression = self.f[1].to_expression(a, milp)
139
- return Expression.subtract_expressions(ex1, ex2)
147
+ return ex1 - ex2
140
148
  elif self.type == FeatureFunctionType.SUM:
149
+ assert len(self.f) >= 1
141
150
  ex1: Expression = self.f[0].to_expression(a, milp)
142
151
  for i in range(1, len(self.f)):
143
152
  ex2: Expression = self.f[i].to_expression(a, milp)
144
- ex1: Expression = Expression.add_expressions(ex1, ex2)
153
+ ex1 = ex1 + ex2
145
154
  return ex1
146
155
  return None
147
156
 
@@ -129,6 +129,8 @@ from pyowl2.individual.named_individual import OWLNamedIndividual
129
129
  from pyowl2.literal.literal import OWLLiteral
130
130
  from pyowl2.ontology import OWLOntology
131
131
 
132
+ from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
133
+
132
134
 
133
135
  # @utils.timer_decorator
134
136
  class FuzzydlToOwl2:
@@ -149,7 +151,7 @@ class FuzzydlToOwl2:
149
151
  self.ontology_iri, OWL1_annotations=True
150
152
  )
151
153
  self.fuzzyLabel: OWLAnnotationProperty = OWLAnnotationProperty(
152
- IRI(self.ontology_iri.namespace, "fuzzyLabel")
154
+ IRI(self.ontology_iri.namespace, ConfigReader.OWL_ANNOTATION_LABEL)
153
155
  )
154
156
 
155
157
  self.ontology.add_axiom(OWLDeclaration(self.fuzzyLabel))