fuzzy-dl-owl2 1.0.7__py3-none-any.whl → 1.0.9__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 (84) 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 +3 -0
  32. fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +169 -27
  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 +2033 -249
  38. fuzzy_dl_owl2/fuzzydl/label.py +18 -10
  39. fuzzy_dl_owl2/fuzzydl/milp/expression.py +33 -23
  40. fuzzy_dl_owl2/fuzzydl/milp/inequation.py +8 -0
  41. fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +720 -22
  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/variable.py +7 -0
  45. fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +3 -0
  46. fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +21 -0
  47. fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +48 -7
  48. fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +7 -0
  49. fuzzy_dl_owl2/fuzzydl/query/__init__.py +1 -0
  50. fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +80 -1
  51. fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +2 -0
  52. fuzzy_dl_owl2/fuzzydl/query/classification_query.py +26 -0
  53. fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +2 -1
  54. fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +4 -0
  55. fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +6 -2
  56. fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +2 -0
  57. fuzzy_dl_owl2/fuzzydl/query/instance_query.py +5 -0
  58. fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +12 -2
  59. fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +6 -1
  60. fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +7 -1
  61. fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +6 -1
  62. fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +15 -1
  63. fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +4 -1
  64. fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +6 -1
  65. fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +7 -1
  66. fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +5 -1
  67. fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +17 -1
  68. fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +47 -7
  69. fuzzy_dl_owl2/fuzzydl/query/query.py +5 -2
  70. fuzzy_dl_owl2/fuzzydl/query/related_query.py +8 -1
  71. fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +17 -0
  72. fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +5 -0
  73. fuzzy_dl_owl2/fuzzydl/range_axiom.py +4 -0
  74. fuzzy_dl_owl2/fuzzydl/relation.py +5 -0
  75. fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +2 -0
  76. fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +3 -0
  77. fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +6 -1
  78. fuzzy_dl_owl2/fuzzydl/util/config_reader.py +17 -27
  79. fuzzy_dl_owl2/fuzzydl/util/constants.py +100 -0
  80. fuzzy_dl_owl2-1.0.9.dist-info/METADATA +848 -0
  81. {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/RECORD +83 -79
  82. fuzzy_dl_owl2-1.0.7.dist-info/METADATA +0 -408
  83. {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/LICENSE +0 -0
  84. {fuzzy_dl_owl2-1.0.7.dist-info → fuzzy_dl_owl2-1.0.9.dist-info}/WHEEL +0 -0
@@ -10,7 +10,12 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class InstanceQuery(Query, ABC):
13
+ """
14
+ Instance checking query
15
+ """
16
+
13
17
  def __init__(self, concept: Concept, individual: Individual) -> None:
18
+ super().__init__()
14
19
  if concept.is_concrete():
15
20
  Util.error(f"Error: {concept} cannot be a concrete concept.")
16
21
 
@@ -9,15 +9,25 @@ from fuzzy_dl_owl2.fuzzydl.query.query import Query
9
9
 
10
10
 
11
11
  class KbSatisfiableQuery(Query):
12
+ """
13
+ Knowledge base satisfiability degree
14
+ """
15
+
16
+ def __init__(self) -> None:
17
+ super().__init__()
12
18
 
13
19
  def preprocess(self, kb: KnowledgeBase) -> None:
14
20
  pass
15
21
 
16
22
  def solve(self, kb: KnowledgeBase) -> Solution:
17
23
  try:
18
- return Solution(1.0) if self.is_consistent_kb(kb) else Solution(False)
24
+ return (
25
+ Solution(1.0)
26
+ if self.is_consistent_kb(kb)
27
+ else Solution(Solution.INCONSISTENT_KB)
28
+ )
19
29
  except InconsistentOntologyException:
20
- return Solution(False)
30
+ return Solution(Solution.INCONSISTENT_KB)
21
31
 
22
32
  def is_consistent_kb(self, kb: KnowledgeBase) -> bool:
23
33
  kb.solve_abox()
@@ -15,6 +15,10 @@ from fuzzy_dl_owl2.fuzzydl.query.instance_query import InstanceQuery
15
15
 
16
16
 
17
17
  class MaxInstanceQuery(InstanceQuery):
18
+ """
19
+ Lowest upper bound of a concept assertion
20
+ """
21
+
18
22
  def __init__(self, concept: Concept, individual: Individual) -> None:
19
23
  super().__init__(concept, individual)
20
24
 
@@ -26,6 +30,7 @@ class MaxInstanceQuery(InstanceQuery):
26
30
  if "(all " in str(self.conc) or "(not (b-some " in str(self.conc):
27
31
  kb.set_dynamic_blocking()
28
32
 
33
+ # a: c >= q
29
34
  kb.add_assertion(self.ind, self.conc, DegreeVariable.get_degree(q))
30
35
  kb.solve_assertions()
31
36
 
@@ -39,7 +44,7 @@ class MaxInstanceQuery(InstanceQuery):
39
44
  self.set_total_time()
40
45
  return sol
41
46
  except InconsistentOntologyException:
42
- return Solution(False)
47
+ return Solution(Solution.INCONSISTENT_KB)
43
48
 
44
49
  def __str__(self) -> str:
45
50
  return f"Is {self.ind} instance of {self.conc} ? <= "
@@ -10,7 +10,13 @@ from fuzzy_dl_owl2.fuzzydl.query.query import Query
10
10
 
11
11
 
12
12
  class MaxQuery(Query):
13
+ """
14
+ Maximize expression query
15
+ """
16
+
13
17
  def __init__(self, expr: Expression) -> None:
18
+ super().__init__()
19
+ # Expression to be maximized
14
20
  self.obj_expr: Expression = Expression.negate_expression(expr)
15
21
 
16
22
  def preprocess(self, kb: KnowledgeBase) -> None:
@@ -25,7 +31,7 @@ class MaxQuery(Query):
25
31
  self.set_total_time()
26
32
  return sol
27
33
  except InconsistentOntologyException:
28
- return Solution(False)
34
+ return Solution(Solution.INCONSISTENT_KB)
29
35
 
30
36
  def __str__(self) -> str:
31
37
  return f"{self.obj_expr} <= "
@@ -16,12 +16,17 @@ from fuzzy_dl_owl2.fuzzydl.query.related_query import RelatedQuery
16
16
 
17
17
 
18
18
  class MaxRelatedQuery(RelatedQuery):
19
+ """
20
+ Lowest upper bound of a role assertion (ind1, ind2, role)
21
+ """
22
+
19
23
  def __init__(self, a: Individual, b: Individual, role_name: str) -> None:
20
24
  self.ind1: Individual = a
21
25
  self.ind2: Individual = b
22
26
  self.role: str = role_name
23
27
 
24
28
  def preprocess(self, kb: KnowledgeBase) -> None:
29
+ # glb(ind1 : b-some R ind2)
25
30
  conc: Concept = HasValueConcept(self.role, self.ind2)
26
31
  q: Variable = kb.milp.get_variable(self.ind1, conc)
27
32
  kb.add_assertion(self.ind1, conc, DegreeVariable.get_degree(q))
@@ -39,7 +44,7 @@ class MaxRelatedQuery(RelatedQuery):
39
44
  self.set_total_time()
40
45
  return sol
41
46
  except InconsistentOntologyException:
42
- return Solution(False)
47
+ return Solution(Solution.INCONSISTENT_KB)
43
48
 
44
49
  def __str__(self) -> str:
45
50
  return f"Is {self.ind1} related to {self.ind2} through {self.role} ? <= "
@@ -18,6 +18,9 @@ from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
18
18
 
19
19
 
20
20
  class MaxSatisfiableQuery(SatisfiableQuery):
21
+ """
22
+ Maximal satisfiability degree of a fuzzy concept.
23
+ """
21
24
 
22
25
  @typing.overload
23
26
  def __init__(self, c: Concept) -> None: ...
@@ -35,9 +38,20 @@ class MaxSatisfiableQuery(SatisfiableQuery):
35
38
  self.__max_sat_query_init_2(*args)
36
39
 
37
40
  def __max_sat_query_init_1(self, c: Concept) -> None:
41
+ """Constructor for a general satisfiability query
42
+
43
+ Args:
44
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
45
+ """
38
46
  super().__init__(c)
39
47
 
40
48
  def __max_sat_query_init_2(self, c: Concept, a: Individual) -> None:
49
+ """Constructor for a satisfiability query involving a specific individual
50
+
51
+ Args:
52
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
53
+ a (Individual): An individual used in the satisfiability test.
54
+ """
41
55
  super().__init__(c, a)
42
56
 
43
57
  def preprocess(self, kb: KnowledgeBase) -> None:
@@ -65,7 +79,7 @@ class MaxSatisfiableQuery(SatisfiableQuery):
65
79
  self.set_total_time()
66
80
  return sol
67
81
  except InconsistentOntologyException:
68
- return Solution(False)
82
+ return Solution(Solution.INCONSISTENT_KB)
69
83
 
70
84
  def __str__(self) -> str:
71
85
  if self.ind is not None:
@@ -22,6 +22,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import LogicOperatorType
22
22
 
23
23
 
24
24
  class MaxSubsumesQuery(SubsumptionQuery):
25
+ """
26
+ Maximize subsumption query.
27
+ """
25
28
 
26
29
  def __init__(self, c1: Concept, c2: Concept, type_: LogicOperatorType) -> None:
27
30
  super().__init__(c1, c2, type_)
@@ -58,7 +61,7 @@ class MaxSubsumesQuery(SubsumptionQuery):
58
61
  self.set_total_time()
59
62
  return sol
60
63
  except InconsistentOntologyException:
61
- return Solution(False)
64
+ return Solution(Solution.INCONSISTENT_KB)
62
65
 
63
66
  def __str__(self) -> str:
64
67
  return f"{self.c1} subsumes {self.c2} ? <= "
@@ -16,6 +16,10 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import VariableType
16
16
 
17
17
 
18
18
  class MinInstanceQuery(InstanceQuery):
19
+ """
20
+ Greatest lower bound of a concept assertion.
21
+ """
22
+
19
23
  def __init__(self, concept: Concept, individual: Individual) -> None:
20
24
  super().__init__(concept, individual)
21
25
 
@@ -27,6 +31,7 @@ class MinInstanceQuery(InstanceQuery):
27
31
  if "(some " in str(self.conc) or "(b-some " in str(self.conc):
28
32
  kb.set_dynamic_blocking()
29
33
 
34
+ # a: not c >= 1-q
30
35
  kb.add_assertion(
31
36
  self.ind,
32
37
  -self.conc,
@@ -44,7 +49,7 @@ class MinInstanceQuery(InstanceQuery):
44
49
  self.set_total_time()
45
50
  return sol
46
51
  except InconsistentOntologyException:
47
- return Solution(False)
52
+ return Solution(Solution.INCONSISTENT_KB)
48
53
 
49
54
  def __str__(self) -> str:
50
55
  return f"Is {self.ind} instance of {self.conc} ? >= "
@@ -10,7 +10,13 @@ from fuzzy_dl_owl2.fuzzydl.query.query import Query
10
10
 
11
11
 
12
12
  class MinQuery(Query):
13
+ """
14
+ Minimize expression query.
15
+ """
16
+
13
17
  def __init__(self, expr: Expression) -> None:
18
+ super().__init__()
19
+ # Expression to be minimized.
14
20
  self.obj_expr = expr
15
21
 
16
22
  def preprocess(self, kb: KnowledgeBase) -> None:
@@ -25,7 +31,7 @@ class MinQuery(Query):
25
31
  self.set_total_time()
26
32
  return sol
27
33
  except InconsistentOntologyException:
28
- return Solution(False)
34
+ return Solution(Solution.INCONSISTENT_KB)
29
35
 
30
36
  def __str__(self) -> str:
31
37
  return f"{self.obj_expr} ? >= "
@@ -17,6 +17,9 @@ from fuzzy_dl_owl2.fuzzydl.query.related_query import RelatedQuery
17
17
 
18
18
 
19
19
  class MinRelatedQuery(RelatedQuery):
20
+ """
21
+ Greatest lower bound of a role assertion (ind1, ind2, role).
22
+ """
20
23
 
21
24
  def __init__(self, a: Individual, b: Individual, role_name: str) -> None:
22
25
  self.ind1: Individual = a
@@ -33,6 +36,7 @@ class MinRelatedQuery(RelatedQuery):
33
36
  if "(some " in str(conc) or "(b-some " in str(conc):
34
37
  kb.set_dynamic_blocking()
35
38
 
39
+ # a: not c >= 1-q
36
40
  kb.add_assertion(
37
41
  self.ind1,
38
42
  -conc,
@@ -51,7 +55,7 @@ class MinRelatedQuery(RelatedQuery):
51
55
  self.set_total_time()
52
56
  return sol
53
57
  except InconsistentOntologyException:
54
- return Solution(False)
58
+ return Solution(Solution.INCONSISTENT_KB)
55
59
 
56
60
  def __str__(self) -> str:
57
61
  return f"Is {self.ind1} related to {self.ind2} through {self.role} ? >= "
@@ -19,6 +19,9 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import VariableType
19
19
 
20
20
 
21
21
  class MinSatisfiableQuery(SatisfiableQuery):
22
+ """
23
+ Minimal satisfiability degree of a fuzzy concept.
24
+ """
22
25
 
23
26
  @typing.overload
24
27
  def __init__(self, c: Concept) -> None: ...
@@ -36,9 +39,22 @@ class MinSatisfiableQuery(SatisfiableQuery):
36
39
  self.__min_sat_query_init_2(*args)
37
40
 
38
41
  def __min_sat_query_init_1(self, c: Concept) -> None:
42
+ """
43
+ Constructor for a general satisfiability query.
44
+
45
+ Args:
46
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
47
+ """
39
48
  super().__init__(c)
40
49
 
41
50
  def __min_sat_query_init_2(self, c: Concept, a: Individual) -> None:
51
+ """
52
+ Constructor for a satisfiability query involving a specific individual.
53
+
54
+ Args:
55
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
56
+ a (Individual): An individual used in the satisfiability test.
57
+ """
42
58
  super().__init__(c, a)
43
59
 
44
60
  def preprocess(self, kb: KnowledgeBase) -> None:
@@ -72,7 +88,7 @@ class MinSatisfiableQuery(SatisfiableQuery):
72
88
  return sol
73
89
 
74
90
  except InconsistentOntologyException:
75
- return Solution(False)
91
+ return Solution(Solution.INCONSISTENT_KB)
76
92
 
77
93
  def __str__(self) -> str:
78
94
  if self.ind is not None:
@@ -1,5 +1,8 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import typing
4
+
5
+ from fuzzy_dl_owl2.fuzzydl.classification_node import ClassificationNode
3
6
  from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
4
7
  from fuzzy_dl_owl2.fuzzydl.concept.implies_concept import ImpliesConcept
5
8
  from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
@@ -19,11 +22,17 @@ from fuzzy_dl_owl2.fuzzydl.util.constants import LogicOperatorType, VariableType
19
22
 
20
23
 
21
24
  class MinSubsumesQuery(SubsumptionQuery):
25
+ """
26
+ Minimize subsumption query.
27
+ """
22
28
 
23
29
  def __init__(self, c1: Concept, c2: Concept, type_: LogicOperatorType) -> None:
24
30
  super().__init__(c1, c2, type_)
25
31
 
26
32
  def preprocess(self, kb: KnowledgeBase) -> None:
33
+ if kb.is_classified():
34
+ return
35
+
27
36
  ind: Individual = kb.get_new_individual()
28
37
 
29
38
  if self.type == LogicOperatorType.LUKASIEWICZ:
@@ -39,6 +48,7 @@ class MinSubsumesQuery(SubsumptionQuery):
39
48
  kb.old_01_variables += 1
40
49
  self.obj_expr: Expression = Expression(Term(1.0, q))
41
50
 
51
+ # a: not c or d >= 1-q
42
52
  kb.add_assertion(
43
53
  ind,
44
54
  -conc,
@@ -46,20 +56,50 @@ class MinSubsumesQuery(SubsumptionQuery):
46
56
  )
47
57
  kb.solve_assertions()
48
58
 
59
+ # def solve(self, kb: KnowledgeBase) -> Solution:
60
+ # try:
61
+ # self.set_initial_time()
62
+ # if ConfigReader.OPTIMIZATIONS == 0 or kb.has_nominals_in_tbox():
63
+ # cloned: KnowledgeBase = kb.clone()
64
+ # cloned.solve_abox()
65
+ # else:
66
+ # cloned: KnowledgeBase = kb.clone_without_abox()
67
+ # self.preprocess(cloned)
68
+ # sol: Solution = cloned.optimize(self.obj_expr)
69
+ # self.set_total_time()
70
+ # return sol
71
+ # except InconsistentOntologyException:
72
+ # return Solution(Solution.INCONSISTENT_KB)
73
+
49
74
  def solve(self, kb: KnowledgeBase) -> Solution:
50
75
  try:
51
76
  self.set_initial_time()
52
- if ConfigReader.OPTIMIZATIONS == 0 or kb.has_nominals_in_tbox():
53
- cloned: KnowledgeBase = kb.clone()
54
- cloned.solve_abox()
77
+ if kb.is_classified() and self.c1.is_atomic() and self.c2.is_atomic():
78
+ n1: typing.Optional[ClassificationNode] = kb.get_classification_node(
79
+ str(self.c1)
80
+ )
81
+ n2: typing.Optional[ClassificationNode] = kb.get_classification_node(
82
+ str(self.c2)
83
+ )
84
+ if n1 is not None and n1.is_thing():
85
+ sol: Solution = Solution(1.0)
86
+ elif n2 is not None and n1.is_thing():
87
+ sol: Solution = Solution(1.0)
88
+ else:
89
+ sol: Solution = Solution(kb.get_subsumption_flags(n1, n2))
55
90
  else:
56
- cloned: KnowledgeBase = kb.clone_without_abox()
57
- self.preprocess(cloned)
58
- sol: Solution = cloned.optimize(self.obj_expr)
91
+ if ConfigReader.OPTIMIZATIONS == 0 or kb.has_nominals_in_tbox():
92
+ cloned: KnowledgeBase = kb.clone()
93
+ cloned.solve_abox()
94
+ else:
95
+ cloned: KnowledgeBase = kb.clone_without_abox()
96
+ self.preprocess(cloned)
97
+ sol: Solution = cloned.optimize(self.obj_expr)
98
+
59
99
  self.set_total_time()
60
100
  return sol
61
101
  except InconsistentOntologyException:
62
- return Solution(False)
102
+ return Solution(Solution.INCONSISTENT_KB)
63
103
 
64
104
  def __str__(self) -> str:
65
105
  return f"{self.c1} subsumes {self.c2} ? >= "
@@ -8,6 +8,7 @@ from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
8
8
 
9
9
 
10
10
  class Query(ABC):
11
+
11
12
  def __init__(self) -> None:
12
13
  self.initial_time: int = 0
13
14
  self.total_time: int = 0
@@ -24,7 +25,9 @@ class Query(ABC):
24
25
 
25
26
  @abstractmethod
26
27
  def preprocess(self, knowledge_base: KnowledgeBase) -> None:
27
- """Preprocess the query with given knowledge base"""
28
+ """
29
+ Performs some preprocessing steps of the query over a fuzzy KB.
30
+ """
28
31
  pass
29
32
 
30
33
  @abstractmethod
@@ -34,5 +37,5 @@ class Query(ABC):
34
37
 
35
38
  @abstractmethod
36
39
  def __str__(self) -> str:
37
- """String representation of the query"""
40
+ """Solves the query over a fuzzy KB"""
38
41
  pass
@@ -1,15 +1,22 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from abc import ABC
4
+
3
5
  from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
4
6
  from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
5
7
  from fuzzy_dl_owl2.fuzzydl.query.query import Query
6
8
 
7
9
 
8
- class RelatedQuery(Query):
10
+ class RelatedQuery(Query, ABC):
11
+ """Entailment of a role assertion query"""
9
12
 
10
13
  def __init__(self) -> None:
11
14
  super().__init__()
15
+ # Abstract role
12
16
  self.role: str = None
17
+ # Subject of the relation.
13
18
  self.ind1: Individual = None
19
+ # Object of the relation.
14
20
  self.ind2: Individual = None
21
+ # Objective expression
15
22
  self.obj_expr: Expression = None
@@ -10,6 +10,7 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
 
11
11
 
12
12
  class SatisfiableQuery(Query):
13
+ """Fuzzy concept satisfiability query."""
13
14
 
14
15
  @typing.overload
15
16
  def __init__(self, c: Concept, a: Individual) -> None: ...
@@ -18,6 +19,7 @@ class SatisfiableQuery(Query):
18
19
  def __init__(self, c: Concept) -> None: ...
19
20
 
20
21
  def __init__(self, *args) -> None:
22
+ super().__init__()
21
23
  assert len(args) in [1, 2]
22
24
  assert isinstance(args[0], Concept)
23
25
  if len(args) == 1:
@@ -27,11 +29,26 @@ class SatisfiableQuery(Query):
27
29
  self.__satisfiable_query_init_1(*args)
28
30
 
29
31
  def __satisfiable_query_init_1(self, c: Concept, a: Individual) -> None:
32
+ """Constructor for a satisfiability query involving a specific individual.
33
+
34
+ Args:
35
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
36
+ a (Individual): An individual used in the satisfiability test.
37
+ """
30
38
  if c.is_concrete():
31
39
  Util.error(f"Error: {c} cannot be a concrete concept.")
40
+ # Fuzzy concept
32
41
  self.conc: Concept = c
42
+ # Optional individual used during the satisfiability test.
33
43
  self.ind: Individual = a
44
+ # Objective expression
34
45
  self.obj_expr: Expression = None
35
46
 
36
47
  def __satisfiable_query_init_2(self, c: Concept) -> None:
48
+ """
49
+ Constructor for a general satisfiability query.
50
+
51
+ Args:
52
+ c (Concept): A fuzzy concept for which the satisfiability is to be tested.
53
+ """
37
54
  self.__init__(c, None)
@@ -10,11 +10,16 @@ from fuzzy_dl_owl2.fuzzydl.util.util import Util
10
10
  class SubsumptionQuery(Query):
11
11
 
12
12
  def __init__(self, c1: Concept, c2: Concept, s_type: LogicOperatorType) -> None:
13
+ super().__init__()
13
14
  if c1.is_concrete():
14
15
  Util.error(f"Error: {c1} cannot be a concrete concept.")
15
16
  if c2.is_concrete():
16
17
  Util.error(f"Error: {c1} cannot be a concrete concept.")
18
+ # Subsumed concept
17
19
  self.c1: Concept = c1
20
+ # Subsumer concept
18
21
  self.c2: Concept = c2
22
+ # Fuzzy implication used
19
23
  self.type: LogicOperatorType = s_type
24
+ # Objective epxression
20
25
  self.obj_expr: Expression = None
@@ -2,6 +2,10 @@ from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
2
2
 
3
3
 
4
4
  class RangeAxiom:
5
+ """
6
+ Role range axiom
7
+ """
8
+
5
9
  def __init__(self, role: str, concept: Concept) -> None:
6
10
  self.role: str = role
7
11
  self.concept: Concept = concept
@@ -8,6 +8,10 @@ if typing.TYPE_CHECKING:
8
8
 
9
9
 
10
10
  class Relation:
11
+ """
12
+ Represents a role assertion of the form (object individual, role, lower bound for the degree) with respect to a subject individual.
13
+ """
14
+
11
15
  def __init__(
12
16
  self, role_name: str, ind1: Individual, ind2: Individual, degree: Degree
13
17
  ):
@@ -38,6 +42,7 @@ class Relation:
38
42
  return self.degree
39
43
 
40
44
  def get_name_without_degree(self) -> str:
45
+ """Gets a printable name of the role assertion without the lower bound"""
41
46
  return f"({self.ind_a}, {self.ind_b}): {self.role_name}"
42
47
 
43
48
  def __repr__(self) -> str:
@@ -5,6 +5,8 @@ from fuzzy_dl_owl2.fuzzydl.restriction.restriction import Restriction
5
5
 
6
6
 
7
7
  class HasValueRestriction(Restriction):
8
+ """Universal restriction formed by a role, a individual and a lower bound degree."""
9
+
8
10
  def __init__(self, role_name: str, individual: str, degree: Degree) -> None:
9
11
  super().__init__(role_name, None, degree)
10
12
  self.ind_name: str = individual
@@ -7,6 +7,8 @@ from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
7
7
 
8
8
 
9
9
  class Restriction:
10
+ """Universal restriction formed by a role, a concept and a lower bound degree."""
11
+
10
12
  def __init__(self, role_name: str, concept: Concept, degree: Degree) -> None:
11
13
  self.role_name: str = role_name
12
14
  self.concept: Concept = concept
@@ -25,6 +27,7 @@ class Restriction:
25
27
  return self.concept
26
28
 
27
29
  def get_name_without_degree(self) -> str:
30
+ """Gets the name of the restriction without the degree."""
28
31
  return f"(all {self.role_name} {self.concept})"
29
32
 
30
33
  def __repr__(self) -> str:
@@ -1,7 +1,12 @@
1
1
  class RoleParentWithDegree:
2
+ """
3
+ Pair of elements (role, degree in [0,1]).
4
+ Given a role, represents a role parent and the inclusion degree.
5
+ """
6
+
2
7
  def __init__(self, parent: str, degree: float) -> None:
3
- self.degree: float = degree
4
8
  self.parent: str = parent
9
+ self.degree: float = degree
5
10
 
6
11
  def get_degree(self) -> float:
7
12
  return self.degree
@@ -1,42 +1,32 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import configparser
4
- import enum
5
4
  import math
6
5
 
7
6
  from fuzzy_dl_owl2.fuzzydl.util import constants
8
7
 
9
8
 
10
- class MILPProvider(enum.StrEnum):
11
- GUROBI = enum.auto()
12
- MIP = enum.auto()
13
- # SCIPY = enum.auto()
14
- PULP = enum.auto()
15
- PULP_GLPK = enum.auto()
16
- PULP_HIGHS = enum.auto()
17
- PULP_CPLEX = enum.auto()
18
-
19
- @staticmethod
20
- def from_str(value: str) -> MILPProvider:
21
- try:
22
- return MILPProvider(value.lower())
23
- except ValueError:
24
- raise ValueError(
25
- f"Invalid MILP provider: {value}. Valid options are: {list(MILPProvider)}"
26
- )
27
-
28
-
29
9
  class ConfigReader:
10
+ # Anywhere pairwise blocking applied. false disables anywhere double blocking; true enables anywher edouble blocking.
30
11
  ANYWHERE_DOUBLE_BLOCKING: bool = True
12
+ # Anywhere simple blocking applied. false disables anywhere simple blocking; true enables anywhere simple blocking.
31
13
  ANYWHERE_SIMPLE_BLOCKING: bool = True
14
+ # Debugging mode
32
15
  DEBUG_PRINT: bool = True
16
+ # Precision of the reasoner
33
17
  EPSILON: float = 0.001
18
+ # Maximum number of new individuals that will be created
34
19
  MAX_INDIVIDUALS: int = -1
20
+ # Number of digits of precision
35
21
  NUMBER_DIGITS: int = 2
22
+ # Level of the optimizations applied. 0 disables optimizations; a positive value enables optimizations.
36
23
  OPTIMIZATIONS: int = 1
24
+ # Rule acyclic TBox optimization applied
37
25
  RULE_ACYCLIC_TBOXES: bool = True
26
+ # XML OWL 2 annotation label used to create and parse Fuzzy OWL 2 ontologies
38
27
  OWL_ANNOTATION_LABEL: str = "fuzzyLabel"
39
- MILP_PROVIDER: MILPProvider = MILPProvider.GUROBI
28
+ # MILP Solver provider used by the reasoner
29
+ MILP_PROVIDER: constants.MILPProvider = constants.MILPProvider.GUROBI
40
30
 
41
31
  @staticmethod
42
32
  def load_parameters(config_file: str, args: list[str]) -> None:
@@ -62,22 +52,22 @@ class ConfigReader:
62
52
  ConfigReader.OWL_ANNOTATION_LABEL = config.get(
63
53
  "DEFAULT", "owlAnnotationLabel"
64
54
  )
65
- ConfigReader.MILP_PROVIDER = MILPProvider(
55
+ ConfigReader.MILP_PROVIDER = constants.MILPProvider(
66
56
  config.get("DEFAULT", "milpProvider").lower()
67
57
  )
68
58
  ConfigReader.NUMBER_DIGITS = int(
69
59
  round(abs(math.log10(ConfigReader.EPSILON) - 1.0))
70
60
  )
71
61
  if ConfigReader.MILP_PROVIDER in [
72
- MILPProvider.MIP,
73
- MILPProvider.PULP,
62
+ constants.MILPProvider.MIP,
63
+ constants.MILPProvider.PULP,
74
64
  ]:
75
65
  constants.MAXVAL = (1 << 31) - 1
76
66
  constants.MAXVAL2 = constants.MAXVAL * 2
77
67
  elif ConfigReader.MILP_PROVIDER in [
78
- MILPProvider.PULP_GLPK,
79
- MILPProvider.PULP_HIGHS,
80
- MILPProvider.PULP_CPLEX,
68
+ constants.MILPProvider.PULP_GLPK,
69
+ constants.MILPProvider.PULP_HIGHS,
70
+ constants.MILPProvider.PULP_CPLEX,
81
71
  # MILPProvider.SCIPY,
82
72
  ]:
83
73
  constants.MAXVAL = (1 << 28) - 1