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.
- fuzzy_dl_owl2/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/__init__.py +23 -0
- fuzzy_dl_owl2/fuzzydl/assertion/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/assertion/assertion.py +72 -0
- fuzzy_dl_owl2/fuzzydl/assertion/atomic_assertion.py +19 -0
- fuzzy_dl_owl2/fuzzydl/concept/__init__.py +13 -0
- fuzzy_dl_owl2/fuzzydl/concept/all_some_concept.py +85 -0
- fuzzy_dl_owl2/fuzzydl/concept/approximation_concept.py +147 -0
- fuzzy_dl_owl2/fuzzydl/concept/atomic_concept.py +91 -0
- fuzzy_dl_owl2/fuzzydl/concept/choquet_integral.py +64 -0
- fuzzy_dl_owl2/fuzzydl/concept/concept.py +230 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/__init__.py +10 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/crisp_concrete_concept.py +60 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_concrete_concept.py +63 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/fuzzy_number/triangular_fuzzy_number.py +127 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/left_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/linear_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/modified_concrete_concept.py +66 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/right_concrete_concept.py +70 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/trapezoidal_concrete_concept.py +96 -0
- fuzzy_dl_owl2/fuzzydl/concept/concrete/triangular_concrete_concept.py +89 -0
- fuzzy_dl_owl2/fuzzydl/concept/ext_threshold_concept.py +77 -0
- fuzzy_dl_owl2/fuzzydl/concept/has_value_concept.py +51 -0
- fuzzy_dl_owl2/fuzzydl/concept/implies_concept.py +144 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/__init__.py +6 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_concept_interface.py +17 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_concepts_interface.py +18 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_concept_interface.py +14 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_role_interface.py +15 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_value_interface.py +21 -0
- fuzzy_dl_owl2/fuzzydl/concept/interface/has_weighted_concepts_interface.py +29 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/linearly_modified_concept.py +32 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/modified_concept.py +59 -0
- fuzzy_dl_owl2/fuzzydl/concept/modified/triangularly_modified_concept.py +33 -0
- fuzzy_dl_owl2/fuzzydl/concept/negated_nominal.py +42 -0
- fuzzy_dl_owl2/fuzzydl/concept/operator_concept.py +707 -0
- fuzzy_dl_owl2/fuzzydl/concept/owa_concept.py +57 -0
- fuzzy_dl_owl2/fuzzydl/concept/qowa_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept/quasi_sugeno_integral.py +46 -0
- fuzzy_dl_owl2/fuzzydl/concept/self_concept.py +45 -0
- fuzzy_dl_owl2/fuzzydl/concept/string_concept.py +35 -0
- fuzzy_dl_owl2/fuzzydl/concept/sugeno_integral.py +83 -0
- fuzzy_dl_owl2/fuzzydl/concept/threshold_concept.py +81 -0
- fuzzy_dl_owl2/fuzzydl/concept/truth_concept.py +83 -0
- fuzzy_dl_owl2/fuzzydl/concept/value_concept.py +67 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_concept.py +55 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_max_concept.py +63 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_min_concept.py +57 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept/weighted_sum_zero_concept.py +62 -0
- fuzzy_dl_owl2/fuzzydl/concept_equivalence.py +20 -0
- fuzzy_dl_owl2/fuzzydl/concrete_feature.py +94 -0
- fuzzy_dl_owl2/fuzzydl/degree/__init__.py +4 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree.py +79 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_expression.py +57 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_numeric.py +57 -0
- fuzzy_dl_owl2/fuzzydl/degree/degree_variable.py +54 -0
- fuzzy_dl_owl2/fuzzydl/domain_axiom.py +8 -0
- fuzzy_dl_owl2/fuzzydl/exception/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/exception/fuzzy_ontology_exception.py +4 -0
- fuzzy_dl_owl2/fuzzydl/exception/inconsistent_ontology_exception.py +4 -0
- fuzzy_dl_owl2/fuzzydl/feature_function.py +148 -0
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2.py +920 -0
- fuzzy_dl_owl2/fuzzydl/fuzzydl_to_owl2_java.py +953 -0
- fuzzy_dl_owl2/fuzzydl/general_concept_inclusion.py +82 -0
- fuzzy_dl_owl2/fuzzydl/individual/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/individual/created_individual.py +219 -0
- fuzzy_dl_owl2/fuzzydl/individual/individual.py +113 -0
- fuzzy_dl_owl2/fuzzydl/individual/representative_individual.py +37 -0
- fuzzy_dl_owl2/fuzzydl/knowledge_base.py +9037 -0
- fuzzy_dl_owl2/fuzzydl/label.py +32 -0
- fuzzy_dl_owl2/fuzzydl/milp/__init__.py +7 -0
- fuzzy_dl_owl2/fuzzydl/milp/expression.py +186 -0
- fuzzy_dl_owl2/fuzzydl/milp/inequation.py +55 -0
- fuzzy_dl_owl2/fuzzydl/milp/milp_helper.py +787 -0
- fuzzy_dl_owl2/fuzzydl/milp/show_variables_helper.py +151 -0
- fuzzy_dl_owl2/fuzzydl/milp/solution.py +45 -0
- fuzzy_dl_owl2/fuzzydl/milp/term.py +76 -0
- fuzzy_dl_owl2/fuzzydl/milp/variable.py +89 -0
- fuzzy_dl_owl2/fuzzydl/modifier/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/modifier/linear_modifier.py +76 -0
- fuzzy_dl_owl2/fuzzydl/modifier/modifier.py +39 -0
- fuzzy_dl_owl2/fuzzydl/modifier/triangular_modifier.py +76 -0
- fuzzy_dl_owl2/fuzzydl/parser/ParserConstants.py +406 -0
- fuzzy_dl_owl2/fuzzydl/parser/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzydl/parser/dl_parser.py +2029 -0
- fuzzy_dl_owl2/fuzzydl/parser/ebnf.lark +290 -0
- fuzzy_dl_owl2/fuzzydl/parser/larkx.py +70 -0
- fuzzy_dl_owl2/fuzzydl/primitive_concept_definition.py +81 -0
- fuzzy_dl_owl2/fuzzydl/query/__init__.py +14 -0
- fuzzy_dl_owl2/fuzzydl/query/all_instances_query.py +50 -0
- fuzzy_dl_owl2/fuzzydl/query/bnp_query.py +22 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/__init__.py +4 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/defuzzify_query.py +76 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/lom_defuzzify_query.py +19 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/mom_defuzzify_query.py +88 -0
- fuzzy_dl_owl2/fuzzydl/query/defuzzify/som_defuzzify_query.py +20 -0
- fuzzy_dl_owl2/fuzzydl/query/instance_query.py +19 -0
- fuzzy_dl_owl2/fuzzydl/query/kb_satisfiable_query.py +32 -0
- fuzzy_dl_owl2/fuzzydl/query/max/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_instance_query.py +45 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_query.py +31 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_related_query.py +45 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_satisfiable_query.py +73 -0
- fuzzy_dl_owl2/fuzzydl/query/max/max_subsumes_query.py +64 -0
- fuzzy_dl_owl2/fuzzydl/query/min/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_instance_query.py +50 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_query.py +31 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_related_query.py +57 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_satisfiable_query.py +80 -0
- fuzzy_dl_owl2/fuzzydl/query/min/min_subsumes_query.py +65 -0
- fuzzy_dl_owl2/fuzzydl/query/query.py +38 -0
- fuzzy_dl_owl2/fuzzydl/query/related_query.py +15 -0
- fuzzy_dl_owl2/fuzzydl/query/satisfiable_query.py +37 -0
- fuzzy_dl_owl2/fuzzydl/query/subsumption_query.py +20 -0
- fuzzy_dl_owl2/fuzzydl/range_axiom.py +7 -0
- fuzzy_dl_owl2/fuzzydl/relation.py +47 -0
- fuzzy_dl_owl2/fuzzydl/restriction/__init__.py +2 -0
- fuzzy_dl_owl2/fuzzydl/restriction/has_value_restriction.py +16 -0
- fuzzy_dl_owl2/fuzzydl/restriction/restriction.py +34 -0
- fuzzy_dl_owl2/fuzzydl/role_parent_with_degree.py +10 -0
- fuzzy_dl_owl2/fuzzydl/util/__init__.py +3 -0
- fuzzy_dl_owl2/fuzzydl/util/config_reader.py +56 -0
- fuzzy_dl_owl2/fuzzydl/util/constants.py +424 -0
- fuzzy_dl_owl2/fuzzydl/util/util.py +73 -0
- fuzzy_dl_owl2/fuzzyowl2/__init__.py +5 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2.py +1513 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_java.py +1409 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl.py +917 -0
- fuzzy_dl_owl2/fuzzyowl2/fuzzyowl2_to_fuzzydl_java.py +956 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/__init__.py +0 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/choquet_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/concept_definition.py +14 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_datatype.py +22 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_modifier.py +4 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_nominal_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/fuzzy_property.py +5 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/left_shoulder_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/linear_modifier.py +13 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/modified_property.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/owa_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/property_definition.py +10 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/qowa_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/quasi_sugeno_concept.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/right_shoulder_function.py +17 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/sugeno_concept.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/trapezoidal_function.py +25 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_function.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/triangular_modifer.py +21 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_concept.py +19 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_max_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_min_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/owl_types/weighted_sum_zero_concept.py +15 -0
- fuzzy_dl_owl2/fuzzyowl2/parser/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzyowl2/parser/owl2_parser.py +491 -0
- fuzzy_dl_owl2/fuzzyowl2/util/__init__.py +1 -0
- fuzzy_dl_owl2/fuzzyowl2/util/constants.py +112 -0
- fuzzy_dl_owl2-1.0.0.dist-info/LICENSE +427 -0
- fuzzy_dl_owl2-1.0.0.dist-info/METADATA +299 -0
- fuzzy_dl_owl2-1.0.0.dist-info/RECORD +167 -0
- fuzzy_dl_owl2-1.0.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,2029 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import datetime
|
|
4
|
+
import os
|
|
5
|
+
import time
|
|
6
|
+
import traceback
|
|
7
|
+
import typing
|
|
8
|
+
from functools import partial, reduce
|
|
9
|
+
|
|
10
|
+
import pyparsing as pp
|
|
11
|
+
|
|
12
|
+
from fuzzy_dl_owl2.fuzzydl.concept.all_some_concept import AllSomeConcept
|
|
13
|
+
from fuzzy_dl_owl2.fuzzydl.concept.approximation_concept import \
|
|
14
|
+
ApproximationConcept
|
|
15
|
+
from fuzzy_dl_owl2.fuzzydl.concept.choquet_integral import ChoquetIntegral
|
|
16
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concept import Concept
|
|
17
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.crisp_concrete_concept import \
|
|
18
|
+
CrispConcreteConcept
|
|
19
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_concrete_concept import \
|
|
20
|
+
FuzzyConcreteConcept
|
|
21
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.fuzzy_number.triangular_fuzzy_number import \
|
|
22
|
+
TriangularFuzzyNumber
|
|
23
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.left_concrete_concept import \
|
|
24
|
+
LeftConcreteConcept
|
|
25
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.linear_concrete_concept import \
|
|
26
|
+
LinearConcreteConcept
|
|
27
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.modified_concrete_concept import \
|
|
28
|
+
ModifiedConcreteConcept
|
|
29
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.right_concrete_concept import \
|
|
30
|
+
RightConcreteConcept
|
|
31
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.trapezoidal_concrete_concept import \
|
|
32
|
+
TrapezoidalConcreteConcept
|
|
33
|
+
from fuzzy_dl_owl2.fuzzydl.concept.concrete.triangular_concrete_concept import \
|
|
34
|
+
TriangularConcreteConcept
|
|
35
|
+
from fuzzy_dl_owl2.fuzzydl.concept.ext_threshold_concept import \
|
|
36
|
+
ExtThresholdConcept
|
|
37
|
+
from fuzzy_dl_owl2.fuzzydl.concept.has_value_concept import HasValueConcept
|
|
38
|
+
from fuzzy_dl_owl2.fuzzydl.concept.implies_concept import ImpliesConcept
|
|
39
|
+
from fuzzy_dl_owl2.fuzzydl.concept.operator_concept import OperatorConcept
|
|
40
|
+
from fuzzy_dl_owl2.fuzzydl.concept.owa_concept import OwaConcept
|
|
41
|
+
from fuzzy_dl_owl2.fuzzydl.concept.qowa_concept import QowaConcept
|
|
42
|
+
from fuzzy_dl_owl2.fuzzydl.concept.quasi_sugeno_integral import \
|
|
43
|
+
QsugenoIntegral
|
|
44
|
+
from fuzzy_dl_owl2.fuzzydl.concept.self_concept import SelfConcept
|
|
45
|
+
from fuzzy_dl_owl2.fuzzydl.concept.sugeno_integral import SugenoIntegral
|
|
46
|
+
from fuzzy_dl_owl2.fuzzydl.concept.threshold_concept import ThresholdConcept
|
|
47
|
+
from fuzzy_dl_owl2.fuzzydl.concept.truth_concept import TruthConcept
|
|
48
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_concept import WeightedConcept
|
|
49
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_max_concept import \
|
|
50
|
+
WeightedMaxConcept
|
|
51
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_min_concept import \
|
|
52
|
+
WeightedMinConcept
|
|
53
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_concept import \
|
|
54
|
+
WeightedSumConcept
|
|
55
|
+
from fuzzy_dl_owl2.fuzzydl.concept.weighted_sum_zero_concept import \
|
|
56
|
+
WeightedSumZeroConcept
|
|
57
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree import Degree
|
|
58
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_expression import DegreeExpression
|
|
59
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_numeric import DegreeNumeric
|
|
60
|
+
from fuzzy_dl_owl2.fuzzydl.degree.degree_variable import DegreeVariable
|
|
61
|
+
from fuzzy_dl_owl2.fuzzydl.exception.inconsistent_ontology_exception import \
|
|
62
|
+
InconsistentOntologyException
|
|
63
|
+
from fuzzy_dl_owl2.fuzzydl.feature_function import FeatureFunction
|
|
64
|
+
from fuzzy_dl_owl2.fuzzydl.individual.individual import Individual
|
|
65
|
+
from fuzzy_dl_owl2.fuzzydl.knowledge_base import KnowledgeBase
|
|
66
|
+
from fuzzy_dl_owl2.fuzzydl.milp.expression import Expression
|
|
67
|
+
from fuzzy_dl_owl2.fuzzydl.milp.solution import Solution
|
|
68
|
+
from fuzzy_dl_owl2.fuzzydl.milp.term import Term
|
|
69
|
+
from fuzzy_dl_owl2.fuzzydl.milp.variable import Variable
|
|
70
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.linear_modifier import LinearModifier
|
|
71
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.modifier import Modifier
|
|
72
|
+
from fuzzy_dl_owl2.fuzzydl.modifier.triangular_modifier import \
|
|
73
|
+
TriangularModifier
|
|
74
|
+
from fuzzy_dl_owl2.fuzzydl.query.all_instances_query import AllInstancesQuery
|
|
75
|
+
from fuzzy_dl_owl2.fuzzydl.query.bnp_query import BnpQuery
|
|
76
|
+
from fuzzy_dl_owl2.fuzzydl.query.defuzzify.lom_defuzzify_query import \
|
|
77
|
+
LomDefuzzifyQuery
|
|
78
|
+
from fuzzy_dl_owl2.fuzzydl.query.defuzzify.mom_defuzzify_query import \
|
|
79
|
+
MomDefuzzifyQuery
|
|
80
|
+
from fuzzy_dl_owl2.fuzzydl.query.defuzzify.som_defuzzify_query import \
|
|
81
|
+
SomDefuzzifyQuery
|
|
82
|
+
from fuzzy_dl_owl2.fuzzydl.query.kb_satisfiable_query import \
|
|
83
|
+
KbSatisfiableQuery
|
|
84
|
+
from fuzzy_dl_owl2.fuzzydl.query.max.max_instance_query import \
|
|
85
|
+
MaxInstanceQuery
|
|
86
|
+
from fuzzy_dl_owl2.fuzzydl.query.max.max_query import MaxQuery
|
|
87
|
+
from fuzzy_dl_owl2.fuzzydl.query.max.max_related_query import MaxRelatedQuery
|
|
88
|
+
from fuzzy_dl_owl2.fuzzydl.query.max.max_satisfiable_query import \
|
|
89
|
+
MaxSatisfiableQuery
|
|
90
|
+
from fuzzy_dl_owl2.fuzzydl.query.max.max_subsumes_query import \
|
|
91
|
+
MaxSubsumesQuery
|
|
92
|
+
from fuzzy_dl_owl2.fuzzydl.query.min.min_instance_query import \
|
|
93
|
+
MinInstanceQuery
|
|
94
|
+
from fuzzy_dl_owl2.fuzzydl.query.min.min_query import MinQuery
|
|
95
|
+
from fuzzy_dl_owl2.fuzzydl.query.min.min_related_query import MinRelatedQuery
|
|
96
|
+
from fuzzy_dl_owl2.fuzzydl.query.min.min_satisfiable_query import \
|
|
97
|
+
MinSatisfiableQuery
|
|
98
|
+
from fuzzy_dl_owl2.fuzzydl.query.min.min_subsumes_query import \
|
|
99
|
+
MinSubsumesQuery
|
|
100
|
+
from fuzzy_dl_owl2.fuzzydl.query.query import Query
|
|
101
|
+
from fuzzy_dl_owl2.fuzzydl.util import constants, utils
|
|
102
|
+
from fuzzy_dl_owl2.fuzzydl.util.config_reader import ConfigReader
|
|
103
|
+
from fuzzy_dl_owl2.fuzzydl.util.constants import (ConceptType, FuzzyDLKeyword,
|
|
104
|
+
FuzzyLogic, InequalityType,
|
|
105
|
+
LogicOperatorType,
|
|
106
|
+
RestrictionType,
|
|
107
|
+
VariableType)
|
|
108
|
+
from fuzzy_dl_owl2.fuzzydl.util.util import Util
|
|
109
|
+
|
|
110
|
+
TODAY: datetime.datetime = datetime.datetime.today()
|
|
111
|
+
LOG_DIR: str = os.path.join(
|
|
112
|
+
".", "logs", "parser", str(TODAY.year), str(TODAY.month), str(TODAY.day)
|
|
113
|
+
)
|
|
114
|
+
FILENAME: str = (
|
|
115
|
+
f"fuzzydl_{str(TODAY.hour).zfill(2)}-{str(TODAY.minute).zfill(2)}-{str(TODAY.second).zfill(2)}.log"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
if not os.path.exists(LOG_DIR):
|
|
119
|
+
os.makedirs(LOG_DIR)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def _check_abstract(c: Concept) -> None:
|
|
123
|
+
if c.is_concrete():
|
|
124
|
+
Util.error(f"Error: Concept {c} should be abstract.")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _to_number(tokens: pp.ParseResults) -> float | int:
|
|
128
|
+
v: float = float(str(tokens.as_list()[0]))
|
|
129
|
+
return int(v) if v.is_integer() else v
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# @pp.trace_parse_action
|
|
133
|
+
def _fuzzy_logic_parser(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
134
|
+
if ConfigReader.DEBUG_PRINT:
|
|
135
|
+
Util.debug(f"\t\t_fuzzy_logic_parser -> {tokens}")
|
|
136
|
+
kb.set_logic(FuzzyLogic(str(tokens.as_list()[0]).lower()))
|
|
137
|
+
return tokens
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def _to_concept(kb: KnowledgeBase, c: typing.Union[str, Concept]) -> Concept:
|
|
141
|
+
if ConfigReader.DEBUG_PRINT:
|
|
142
|
+
Util.debug(f"\t\t_to_concept -> {c}")
|
|
143
|
+
return c if isinstance(c, Concept) else kb.get_concept(c)
|
|
144
|
+
# return kb.get_concept(str(c))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def _to_top_bottom_concept(
|
|
148
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
149
|
+
) -> pp.ParseResults:
|
|
150
|
+
if ConfigReader.DEBUG_PRINT:
|
|
151
|
+
Util.debug(f"\t\t_to_top_bottom_concept -> {tokens}")
|
|
152
|
+
list_tokens: list = tokens.as_list()
|
|
153
|
+
if list_tokens[0] == FuzzyDLKeyword.TOP:
|
|
154
|
+
return pp.ParseResults([TruthConcept.get_top()])
|
|
155
|
+
elif list_tokens[0] == FuzzyDLKeyword.BOTTOM:
|
|
156
|
+
return pp.ParseResults([TruthConcept.get_bottom()])
|
|
157
|
+
else:
|
|
158
|
+
return pp.ParseResults([_to_concept(kb, list_tokens[0])])
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _get_modifier(kb: KnowledgeBase, m: str) -> Modifier:
|
|
162
|
+
if ConfigReader.DEBUG_PRINT:
|
|
163
|
+
Util.debug(f"\t\t_get_modifier -> {m}")
|
|
164
|
+
if len(kb.modifiers) == 0 or m not in kb.modifiers:
|
|
165
|
+
Util.error(f"Error: {m} modifier is not defined.")
|
|
166
|
+
return kb.modifiers.get(m)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def _parse_binary_concept(
|
|
170
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
171
|
+
) -> pp.ParseResults:
|
|
172
|
+
if ConfigReader.DEBUG_PRINT:
|
|
173
|
+
Util.debug(f"\t\t_parse_binary_concept -> {tokens}")
|
|
174
|
+
list_tokens: list = tokens.as_list()
|
|
175
|
+
operator: str = list_tokens[0]
|
|
176
|
+
if operator == FuzzyDLKeyword.AND:
|
|
177
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
178
|
+
for c in list_tokens:
|
|
179
|
+
_check_abstract(c)
|
|
180
|
+
if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
|
|
181
|
+
return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
|
|
182
|
+
elif kb.get_logic() == FuzzyLogic.ZADEH:
|
|
183
|
+
return pp.ParseResults([OperatorConcept.goedel_and(*list_tokens)])
|
|
184
|
+
return pp.ParseResults([OperatorConcept.and_(*list_tokens)])
|
|
185
|
+
elif operator == FuzzyDLKeyword.LUKASIEWICZ_AND:
|
|
186
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
187
|
+
if kb.get_logic() == FuzzyLogic.CLASSICAL:
|
|
188
|
+
Util.error(
|
|
189
|
+
"Error: LUKASIEWICZ_AND cannot be used under classical reasoner."
|
|
190
|
+
)
|
|
191
|
+
for c in list_tokens:
|
|
192
|
+
_check_abstract(c)
|
|
193
|
+
return pp.ParseResults([OperatorConcept.lukasiewicz_and(*list_tokens)])
|
|
194
|
+
elif operator == FuzzyDLKeyword.GOEDEL_AND:
|
|
195
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
196
|
+
if kb.get_logic() == FuzzyLogic.CLASSICAL:
|
|
197
|
+
Util.error("Error: GOEDEL_AND cannot be used under classical reasoner.")
|
|
198
|
+
for c in list_tokens:
|
|
199
|
+
_check_abstract(c)
|
|
200
|
+
return pp.ParseResults([OperatorConcept.goedel_and(*list_tokens)])
|
|
201
|
+
elif operator == FuzzyDLKeyword.OR:
|
|
202
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
203
|
+
for c in list_tokens:
|
|
204
|
+
_check_abstract(c)
|
|
205
|
+
if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
|
|
206
|
+
return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
|
|
207
|
+
elif kb.get_logic() == FuzzyLogic.ZADEH:
|
|
208
|
+
return pp.ParseResults([OperatorConcept.goedel_or(*list_tokens)])
|
|
209
|
+
return pp.ParseResults([OperatorConcept.or_(*list_tokens)])
|
|
210
|
+
elif operator == FuzzyDLKeyword.LUKASIEWICZ_OR:
|
|
211
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
212
|
+
if kb.get_logic() == FuzzyLogic.CLASSICAL:
|
|
213
|
+
Util.error("Error: LUKASIEWICZ_OR cannot be used under classical reasoner.")
|
|
214
|
+
for c in list_tokens:
|
|
215
|
+
_check_abstract(c)
|
|
216
|
+
return pp.ParseResults([OperatorConcept.lukasiewicz_or(*list_tokens)])
|
|
217
|
+
elif operator == FuzzyDLKeyword.GOEDEL_OR:
|
|
218
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
219
|
+
if kb.get_logic() == FuzzyLogic.CLASSICAL:
|
|
220
|
+
Util.error("Error: GOEDEL_OR cannot be used under classical reasoner.")
|
|
221
|
+
for c in list_tokens:
|
|
222
|
+
_check_abstract(c)
|
|
223
|
+
return pp.ParseResults([OperatorConcept.goedel_or(*list_tokens)])
|
|
224
|
+
elif operator in (
|
|
225
|
+
FuzzyDLKeyword.IMPLIES,
|
|
226
|
+
FuzzyDLKeyword.GOEDEL_IMPLIES,
|
|
227
|
+
FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
|
|
228
|
+
FuzzyDLKeyword.ZADEH_IMPLIES,
|
|
229
|
+
FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
|
|
230
|
+
):
|
|
231
|
+
list_tokens: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
232
|
+
for c in list_tokens:
|
|
233
|
+
_check_abstract(c)
|
|
234
|
+
if kb.get_logic() == FuzzyLogic.ZADEH:
|
|
235
|
+
return pp.ParseResults(
|
|
236
|
+
[ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
|
|
237
|
+
)
|
|
238
|
+
elif kb.get_logic() == FuzzyLogic.CLASSICAL:
|
|
239
|
+
if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
|
|
240
|
+
Util.error(
|
|
241
|
+
"Error: GOEDEL_IMPLIES cannot be used under classical reasoner."
|
|
242
|
+
)
|
|
243
|
+
elif operator == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
|
|
244
|
+
Util.error(
|
|
245
|
+
"Error: LUKASIEWICZ_IMPLIES cannot be used under classical reasoner."
|
|
246
|
+
)
|
|
247
|
+
elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
|
|
248
|
+
Util.error(
|
|
249
|
+
"Error: ZADEH_IMPLIES cannot be used under classical reasoner."
|
|
250
|
+
)
|
|
251
|
+
elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
|
|
252
|
+
Util.error(
|
|
253
|
+
"Error: KLEENE_DIENES_IMPLIES cannot be used under classical reasoner."
|
|
254
|
+
)
|
|
255
|
+
if operator == FuzzyDLKeyword.GOEDEL_IMPLIES:
|
|
256
|
+
return pp.ParseResults(
|
|
257
|
+
[ImpliesConcept.goedel_implies(list_tokens[0], list_tokens[1])]
|
|
258
|
+
)
|
|
259
|
+
elif operator == FuzzyDLKeyword.ZADEH_IMPLIES:
|
|
260
|
+
return pp.ParseResults(
|
|
261
|
+
[ImpliesConcept.zadeh_implies(list_tokens[0], list_tokens[1])]
|
|
262
|
+
)
|
|
263
|
+
elif operator == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
|
|
264
|
+
return pp.ParseResults(
|
|
265
|
+
[ImpliesConcept.kleene_dienes_implies(list_tokens[0], list_tokens[1])]
|
|
266
|
+
)
|
|
267
|
+
return pp.ParseResults(
|
|
268
|
+
[ImpliesConcept.lukasiewicz_implies(list_tokens[0], list_tokens[1])]
|
|
269
|
+
)
|
|
270
|
+
elif operator == FuzzyDLKeyword.ALL:
|
|
271
|
+
role: str = list_tokens[1]
|
|
272
|
+
concept: Concept = _to_concept(kb, list_tokens[2])
|
|
273
|
+
kb.check_role(role, concept)
|
|
274
|
+
return pp.ParseResults([AllSomeConcept.all(role, concept)])
|
|
275
|
+
elif operator == FuzzyDLKeyword.SOME:
|
|
276
|
+
c: Concept = _to_concept(kb, list_tokens[2])
|
|
277
|
+
role: str = list_tokens[1]
|
|
278
|
+
kb.check_role(role, c)
|
|
279
|
+
return pp.ParseResults([AllSomeConcept.some(role, c)])
|
|
280
|
+
elif operator == FuzzyDLKeyword.HAS_VALUE:
|
|
281
|
+
ind: Individual = kb.get_individual(list_tokens[2])
|
|
282
|
+
kb.check_role(role, TruthConcept.get_top())
|
|
283
|
+
return pp.ParseResults([HasValueConcept.has_value(role, ind)])
|
|
284
|
+
elif operator in (
|
|
285
|
+
FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION,
|
|
286
|
+
FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION,
|
|
287
|
+
FuzzyDLKeyword.UPPER_APPROXIMATION,
|
|
288
|
+
FuzzyDLKeyword.LOWER_APPROXIMATION,
|
|
289
|
+
FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION,
|
|
290
|
+
FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION,
|
|
291
|
+
):
|
|
292
|
+
role: str = list_tokens[1]
|
|
293
|
+
concept: Concept = _to_concept(kb, list_tokens[2])
|
|
294
|
+
if role not in kb.similarity_relations:
|
|
295
|
+
Util.error(f"Error: Similarity relation {role} has not been defined.")
|
|
296
|
+
if operator == FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION:
|
|
297
|
+
return pp.ParseResults(
|
|
298
|
+
[ApproximationConcept.tight_upper_approx(role, concept)]
|
|
299
|
+
)
|
|
300
|
+
elif operator == FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION:
|
|
301
|
+
return pp.ParseResults(
|
|
302
|
+
[ApproximationConcept.tight_lower_approx(role, concept)]
|
|
303
|
+
)
|
|
304
|
+
elif operator == FuzzyDLKeyword.UPPER_APPROXIMATION:
|
|
305
|
+
return pp.ParseResults([ApproximationConcept.upper_approx(role, concept)])
|
|
306
|
+
elif operator == FuzzyDLKeyword.LOWER_APPROXIMATION:
|
|
307
|
+
return pp.ParseResults([ApproximationConcept.lower_approx(role, concept)])
|
|
308
|
+
elif operator == FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION:
|
|
309
|
+
return pp.ParseResults(
|
|
310
|
+
[ApproximationConcept.loose_upper_approx(role, concept)]
|
|
311
|
+
)
|
|
312
|
+
elif operator == FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION:
|
|
313
|
+
return pp.ParseResults(
|
|
314
|
+
[ApproximationConcept.loose_lower_approx(role, concept)]
|
|
315
|
+
)
|
|
316
|
+
return tokens
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def _parse_unary_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
320
|
+
if ConfigReader.DEBUG_PRINT:
|
|
321
|
+
Util.debug(f"\t\t_parse_unary_concept -> {tokens}")
|
|
322
|
+
list_tokens: list[str] = tokens.as_list()
|
|
323
|
+
operator: str = list_tokens[0]
|
|
324
|
+
if operator == FuzzyDLKeyword.NOT:
|
|
325
|
+
concept: Concept = _to_concept(kb, list_tokens[1])
|
|
326
|
+
return pp.ParseResults([-concept])
|
|
327
|
+
elif operator == FuzzyDLKeyword.SELF:
|
|
328
|
+
role: str = list_tokens[1]
|
|
329
|
+
if role in kb.concrete_roles:
|
|
330
|
+
Util.error(f"Error: Role {role} cannot be concrete and abstract.")
|
|
331
|
+
kb.abstract_roles.add(role)
|
|
332
|
+
return pp.ParseResults([SelfConcept.self(role)])
|
|
333
|
+
return tokens
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def _parse_modifier_concept(
|
|
337
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
338
|
+
) -> pp.ParseResults:
|
|
339
|
+
if ConfigReader.DEBUG_PRINT:
|
|
340
|
+
Util.debug(f"\t\t_parse_modifier_concept -> {tokens}")
|
|
341
|
+
list_tokens: list[str] = tokens.as_list()
|
|
342
|
+
mod: Modifier = _get_modifier(kb, list_tokens[0])
|
|
343
|
+
concept: Concept = _to_concept(kb, list_tokens[1])
|
|
344
|
+
return pp.ParseResults([mod.modify(concept)])
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def _parse_threshold_concept(kb: KnowledgeBase, tokens: pp.ParseResults):
|
|
348
|
+
if ConfigReader.DEBUG_PRINT:
|
|
349
|
+
Util.debug(f"\t\t_parse_threshold_concept -> {tokens}")
|
|
350
|
+
list_tokens: list[str] = tokens.as_list()
|
|
351
|
+
operator: str = list_tokens[0]
|
|
352
|
+
concept: Concept = _to_concept(kb, list_tokens[2])
|
|
353
|
+
_check_abstract(concept)
|
|
354
|
+
if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
|
|
355
|
+
if isinstance(list_tokens[1], (int, float)):
|
|
356
|
+
return pp.ParseResults(
|
|
357
|
+
[ThresholdConcept.pos_threshold(list_tokens[1], concept)]
|
|
358
|
+
)
|
|
359
|
+
elif isinstance(list_tokens[1], str):
|
|
360
|
+
return pp.ParseResults(
|
|
361
|
+
[
|
|
362
|
+
ExtThresholdConcept.extended_pos_threshold(
|
|
363
|
+
kb.milp.get_variable(list_tokens[1]), concept
|
|
364
|
+
)
|
|
365
|
+
]
|
|
366
|
+
)
|
|
367
|
+
elif operator == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
|
|
368
|
+
if isinstance(list_tokens[1], (int, float)):
|
|
369
|
+
return pp.ParseResults(
|
|
370
|
+
[ThresholdConcept.neg_threshold(list_tokens[1], concept)]
|
|
371
|
+
)
|
|
372
|
+
elif isinstance(list_tokens[1], str):
|
|
373
|
+
return pp.ParseResults(
|
|
374
|
+
[
|
|
375
|
+
ExtThresholdConcept.extended_neg_threshold(
|
|
376
|
+
kb.milp.get_variable(list_tokens[1]), concept
|
|
377
|
+
)
|
|
378
|
+
]
|
|
379
|
+
)
|
|
380
|
+
elif operator == FuzzyDLKeyword.EQUALS:
|
|
381
|
+
if isinstance(list_tokens[1], (int, float)):
|
|
382
|
+
return pp.ParseResults([ThresholdConcept.ea(list_tokens[1], concept)])
|
|
383
|
+
elif isinstance(list_tokens[1], str):
|
|
384
|
+
return pp.ParseResults(
|
|
385
|
+
[
|
|
386
|
+
ExtThresholdConcept.extended_neg_threshold(
|
|
387
|
+
kb.milp.get_variable(list_tokens[1]), concept
|
|
388
|
+
)
|
|
389
|
+
]
|
|
390
|
+
)
|
|
391
|
+
return tokens
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
def _parse_weighted_concept_simple(
|
|
395
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
396
|
+
) -> pp.ParseResults:
|
|
397
|
+
if ConfigReader.DEBUG_PRINT:
|
|
398
|
+
Util.debug(f"\t\t_parse_weighted_concept_simple -> {tokens}")
|
|
399
|
+
list_tokens: list[str] = tokens.as_list()
|
|
400
|
+
weight: float = list_tokens[0]
|
|
401
|
+
concept: Concept = _to_concept(kb, list_tokens[1])
|
|
402
|
+
return pp.ParseResults([WeightedConcept(weight, concept)])
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def _parse_weighted_concept(
|
|
406
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
407
|
+
) -> pp.ParseResults:
|
|
408
|
+
if ConfigReader.DEBUG_PRINT:
|
|
409
|
+
Util.debug(f"\t\t_parse_weighted_concept -> {tokens}")
|
|
410
|
+
list_tokens: list[str] = tokens.as_list()
|
|
411
|
+
operator: str = list_tokens[0]
|
|
412
|
+
assert all(isinstance(c, WeightedConcept) for c in list_tokens[1:])
|
|
413
|
+
weights: list[float] = list(map(lambda x: x.weight, list_tokens[1:]))
|
|
414
|
+
if sum(weights) != 1.0:
|
|
415
|
+
Util.error("Error: The sum of the weights must be equal to 1.")
|
|
416
|
+
concepts: list[Concept] = [
|
|
417
|
+
_to_concept(kb, w_concept.curr_concept) for w_concept in list_tokens[1:]
|
|
418
|
+
]
|
|
419
|
+
if operator == FuzzyDLKeyword.W_SUM:
|
|
420
|
+
return pp.ParseResults([WeightedSumConcept(weights, concepts)])
|
|
421
|
+
elif operator == FuzzyDLKeyword.W_MAX:
|
|
422
|
+
return pp.ParseResults([WeightedMaxConcept(weights, concepts)])
|
|
423
|
+
elif operator == FuzzyDLKeyword.W_MIN:
|
|
424
|
+
return pp.ParseResults([WeightedMinConcept(weights, concepts)])
|
|
425
|
+
elif operator == FuzzyDLKeyword.W_SUM_ZERO:
|
|
426
|
+
return pp.ParseResults([WeightedSumZeroConcept(weights, concepts)])
|
|
427
|
+
return tokens
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def _parse_q_owa_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
431
|
+
if ConfigReader.DEBUG_PRINT:
|
|
432
|
+
Util.debug(f"\t\t_parse_q_owa_concept -> {tokens}")
|
|
433
|
+
list_tokens: list[str] = tokens.as_list()
|
|
434
|
+
f: FuzzyConcreteConcept = kb.concrete_concepts.get(list_tokens[0])
|
|
435
|
+
if f is None:
|
|
436
|
+
Util.error(f"Error: Fuzzy concept {f} has to be defined before being used.")
|
|
437
|
+
if not isinstance(f, (RightConcreteConcept, LeftConcreteConcept)):
|
|
438
|
+
Util.error(f"Error: Fuzzy concept {f} has to be a right or a linear function.")
|
|
439
|
+
concepts: list[Concept] = [_to_concept(kb, concept) for concept in list_tokens[1:]]
|
|
440
|
+
return pp.ParseResults([QowaConcept(f, concepts)])
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
def _parse_owa_integral_concept(
|
|
444
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
445
|
+
) -> pp.ParseResults:
|
|
446
|
+
if ConfigReader.DEBUG_PRINT:
|
|
447
|
+
Util.debug(f"\t\t_parse_owa_integral_concept -> {tokens}")
|
|
448
|
+
list_tokens: list[str] = tokens.as_list()
|
|
449
|
+
operator: str = list_tokens[0]
|
|
450
|
+
length: int = len(list_tokens) - 1
|
|
451
|
+
assert length % 2 == 0
|
|
452
|
+
weights: list[float] = list_tokens[1:][: length // 2]
|
|
453
|
+
concepts: list[Concept] = [
|
|
454
|
+
_to_concept(kb, concept) for concept in list_tokens[1:][length // 2 :]
|
|
455
|
+
]
|
|
456
|
+
if operator == FuzzyDLKeyword.OWA:
|
|
457
|
+
return pp.ParseResults([OwaConcept(weights, concepts)])
|
|
458
|
+
elif operator == FuzzyDLKeyword.CHOQUET:
|
|
459
|
+
return pp.ParseResults([ChoquetIntegral(weights, concepts)])
|
|
460
|
+
elif operator == FuzzyDLKeyword.SUGENO:
|
|
461
|
+
return pp.ParseResults([SugenoIntegral(weights, concepts)])
|
|
462
|
+
elif operator == FuzzyDLKeyword.QUASI_SUGENO:
|
|
463
|
+
return pp.ParseResults([QsugenoIntegral(weights, concepts)])
|
|
464
|
+
return tokens
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def _parse_modifier(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
468
|
+
if ConfigReader.DEBUG_PRINT:
|
|
469
|
+
Util.debug(f"\t\t_parse_modifier -> {tokens}")
|
|
470
|
+
|
|
471
|
+
list_tokens: list[str] = tokens.as_list()
|
|
472
|
+
if list_tokens[1] == FuzzyDLKeyword.LINEAR_MODIFIER:
|
|
473
|
+
kb.add_modifier(list_tokens[0], LinearModifier(list_tokens[0], list_tokens[2]))
|
|
474
|
+
elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR_MODIFIER:
|
|
475
|
+
kb.add_modifier(
|
|
476
|
+
list_tokens[0],
|
|
477
|
+
TriangularModifier(
|
|
478
|
+
list_tokens[0], list_tokens[2], list_tokens[3], list_tokens[4]
|
|
479
|
+
),
|
|
480
|
+
)
|
|
481
|
+
return tokens
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
def _parse_truth_constants(
|
|
485
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
486
|
+
) -> pp.ParseResults:
|
|
487
|
+
if ConfigReader.DEBUG_PRINT:
|
|
488
|
+
Util.debug(f"\t\t_parse_truth_constants -> {tokens}")
|
|
489
|
+
list_tokens: list[str] = tokens.as_list()
|
|
490
|
+
kb.set_truth_constants(list_tokens[0], list_tokens[1])
|
|
491
|
+
return tokens
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
def _parse_fuzzy_concept(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
495
|
+
if ConfigReader.DEBUG_PRINT:
|
|
496
|
+
Util.debug(f"\t\t_parse_fuzzy_concept -> {tokens}")
|
|
497
|
+
list_tokens: list = tokens.as_list()
|
|
498
|
+
if kb.concrete_concepts.get(list_tokens[0]) is not None:
|
|
499
|
+
Util.error(
|
|
500
|
+
f"Error: Fuzzy concept {list_tokens[0]} has to be defined before being used."
|
|
501
|
+
)
|
|
502
|
+
if (
|
|
503
|
+
list_tokens[1] != FuzzyDLKeyword.CRISP
|
|
504
|
+
and kb.get_logic() == FuzzyLogic.CLASSICAL
|
|
505
|
+
):
|
|
506
|
+
Util.error(
|
|
507
|
+
f"Error: Fuzzy concept {list_tokens[0]} cannot be used with the classical reasoner."
|
|
508
|
+
)
|
|
509
|
+
if list_tokens[1] == FuzzyDLKeyword.CRISP:
|
|
510
|
+
kb.add_concept(
|
|
511
|
+
list_tokens[0],
|
|
512
|
+
CrispConcreteConcept(
|
|
513
|
+
list_tokens[0],
|
|
514
|
+
list_tokens[2],
|
|
515
|
+
list_tokens[3],
|
|
516
|
+
list_tokens[4],
|
|
517
|
+
list_tokens[5],
|
|
518
|
+
),
|
|
519
|
+
)
|
|
520
|
+
elif list_tokens[1] == FuzzyDLKeyword.LEFT_SHOULDER:
|
|
521
|
+
kb.add_concept(
|
|
522
|
+
list_tokens[0],
|
|
523
|
+
LeftConcreteConcept(
|
|
524
|
+
list_tokens[0],
|
|
525
|
+
list_tokens[2],
|
|
526
|
+
list_tokens[3],
|
|
527
|
+
list_tokens[4],
|
|
528
|
+
list_tokens[5],
|
|
529
|
+
),
|
|
530
|
+
)
|
|
531
|
+
kb.concrete_fuzzy_concepts = True
|
|
532
|
+
elif list_tokens[1] == FuzzyDLKeyword.RIGHT_SHOULDER:
|
|
533
|
+
kb.add_concept(
|
|
534
|
+
list_tokens[0],
|
|
535
|
+
RightConcreteConcept(
|
|
536
|
+
list_tokens[0],
|
|
537
|
+
list_tokens[2],
|
|
538
|
+
list_tokens[3],
|
|
539
|
+
list_tokens[4],
|
|
540
|
+
list_tokens[5],
|
|
541
|
+
),
|
|
542
|
+
)
|
|
543
|
+
kb.concrete_fuzzy_concepts = True
|
|
544
|
+
elif list_tokens[1] == FuzzyDLKeyword.TRIANGULAR:
|
|
545
|
+
kb.add_concept(
|
|
546
|
+
list_tokens[0],
|
|
547
|
+
TriangularConcreteConcept(
|
|
548
|
+
list_tokens[0],
|
|
549
|
+
list_tokens[2],
|
|
550
|
+
list_tokens[3],
|
|
551
|
+
list_tokens[4],
|
|
552
|
+
list_tokens[5],
|
|
553
|
+
list_tokens[6],
|
|
554
|
+
),
|
|
555
|
+
)
|
|
556
|
+
kb.concrete_fuzzy_concepts = True
|
|
557
|
+
elif list_tokens[1] == FuzzyDLKeyword.TRAPEZOIDAL:
|
|
558
|
+
kb.add_concept(
|
|
559
|
+
list_tokens[0],
|
|
560
|
+
TrapezoidalConcreteConcept(
|
|
561
|
+
list_tokens[0],
|
|
562
|
+
list_tokens[2],
|
|
563
|
+
list_tokens[3],
|
|
564
|
+
list_tokens[4],
|
|
565
|
+
list_tokens[5],
|
|
566
|
+
list_tokens[6],
|
|
567
|
+
list_tokens[7],
|
|
568
|
+
),
|
|
569
|
+
)
|
|
570
|
+
kb.concrete_fuzzy_concepts = True
|
|
571
|
+
elif list_tokens[1] == FuzzyDLKeyword.LINEAR:
|
|
572
|
+
kb.add_concept(
|
|
573
|
+
list_tokens[0],
|
|
574
|
+
LinearConcreteConcept(
|
|
575
|
+
list_tokens[0],
|
|
576
|
+
list_tokens[2],
|
|
577
|
+
list_tokens[3],
|
|
578
|
+
list_tokens[4],
|
|
579
|
+
list_tokens[5],
|
|
580
|
+
),
|
|
581
|
+
)
|
|
582
|
+
kb.concrete_fuzzy_concepts = True
|
|
583
|
+
elif list_tokens[1] == FuzzyDLKeyword.MODIFIED:
|
|
584
|
+
mod: Modifier = _get_modifier(kb, list_tokens[2])
|
|
585
|
+
if kb.concrete_concepts.get(list_tokens[3]) is None:
|
|
586
|
+
Util.error(
|
|
587
|
+
f"Error: Fuzzy concept {list_tokens[3]} has to be defined before being used."
|
|
588
|
+
)
|
|
589
|
+
kb.add_concept(
|
|
590
|
+
list_tokens[0],
|
|
591
|
+
ModifiedConcreteConcept(
|
|
592
|
+
list_tokens[0],
|
|
593
|
+
mod,
|
|
594
|
+
kb.concrete_concepts.get(list_tokens[3]),
|
|
595
|
+
),
|
|
596
|
+
)
|
|
597
|
+
kb.concrete_fuzzy_concepts = True
|
|
598
|
+
return tokens
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
def _parse_fuzzy_number_range(
|
|
602
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
603
|
+
) -> pp.ParseResults:
|
|
604
|
+
if ConfigReader.DEBUG_PRINT:
|
|
605
|
+
Util.debug(f"\t\t_parse_fuzzy_number_range -> {tokens}")
|
|
606
|
+
tokens = tokens.as_list()
|
|
607
|
+
TriangularFuzzyNumber.set_range(tokens[0], tokens[1])
|
|
608
|
+
return pp.ParseResults(tokens)
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
def _create_fuzzy_number(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
612
|
+
if ConfigReader.DEBUG_PRINT:
|
|
613
|
+
Util.debug(f"\t\t_create_fuzzy_number -> {tokens}")
|
|
614
|
+
tokens = tokens.as_list()
|
|
615
|
+
if len(tokens) == 1:
|
|
616
|
+
if isinstance(tokens[0], (int, float)):
|
|
617
|
+
return pp.ParseResults(
|
|
618
|
+
[TriangularFuzzyNumber(tokens[0], tokens[0], tokens[0])]
|
|
619
|
+
)
|
|
620
|
+
elif tokens[0] == str:
|
|
621
|
+
if tokens[0] not in kb.fuzzy_numbers:
|
|
622
|
+
Util.error(
|
|
623
|
+
f"Error: Fuzzy number {tokens[0]} has to be defined before being used."
|
|
624
|
+
)
|
|
625
|
+
return pp.ParseResults([kb.fuzzy_numbers.get(tokens[0])])
|
|
626
|
+
elif all(isinstance(t, (int, float)) for t in tokens):
|
|
627
|
+
return pp.ParseResults([TriangularFuzzyNumber(tokens[0], tokens[1], tokens[2])])
|
|
628
|
+
return pp.ParseResults(tokens)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def _set_fuzzy_number(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
632
|
+
if ConfigReader.DEBUG_PRINT:
|
|
633
|
+
Util.debug(f"\t\t_set_fuzzy_number -> {tokens}")
|
|
634
|
+
tokens = tokens.as_list()
|
|
635
|
+
if tokens[0] in kb.fuzzy_numbers:
|
|
636
|
+
Util.error(f"Error: Fuzzy number {tokens[0]} has already been defined.")
|
|
637
|
+
if isinstance(tokens[1], TriangularFuzzyNumber):
|
|
638
|
+
kb.add_fuzzy_number(tokens[0], tokens[1])
|
|
639
|
+
kb.concrete_fuzzy_concepts = True
|
|
640
|
+
return pp.ParseResults([tokens[1]])
|
|
641
|
+
elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUM, FuzzyDLKeyword.FEATURE_MUL):
|
|
642
|
+
ts: TriangularFuzzyNumber = [
|
|
643
|
+
typing.cast(TriangularFuzzyNumber, t) for t in tokens[2:]
|
|
644
|
+
]
|
|
645
|
+
result: TriangularFuzzyNumber = reduce(
|
|
646
|
+
(
|
|
647
|
+
TriangularFuzzyNumber.add
|
|
648
|
+
if tokens[1] == FuzzyDLKeyword.FEATURE_SUM
|
|
649
|
+
else TriangularFuzzyNumber.times
|
|
650
|
+
),
|
|
651
|
+
ts,
|
|
652
|
+
)
|
|
653
|
+
kb.add_fuzzy_number(
|
|
654
|
+
tokens[0],
|
|
655
|
+
result,
|
|
656
|
+
)
|
|
657
|
+
kb.concrete_fuzzy_concepts = True
|
|
658
|
+
return pp.ParseResults([result])
|
|
659
|
+
elif tokens[1] in (FuzzyDLKeyword.FEATURE_SUB, FuzzyDLKeyword.FEATURE_DIV):
|
|
660
|
+
t1: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[2])
|
|
661
|
+
t2: TriangularFuzzyNumber = typing.cast(TriangularFuzzyNumber, tokens[3])
|
|
662
|
+
result: TriangularFuzzyNumber = (
|
|
663
|
+
t1.minus(t2)
|
|
664
|
+
if tokens[1] == FuzzyDLKeyword.FEATURE_SUB
|
|
665
|
+
else t1.divided_by(t2)
|
|
666
|
+
)
|
|
667
|
+
kb.add_fuzzy_number(
|
|
668
|
+
tokens[0],
|
|
669
|
+
result,
|
|
670
|
+
)
|
|
671
|
+
kb.concrete_fuzzy_concepts = True
|
|
672
|
+
return pp.ParseResults([result])
|
|
673
|
+
return pp.ParseResults(tokens)
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
def _parse_feature(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
677
|
+
if ConfigReader.DEBUG_PRINT:
|
|
678
|
+
Util.debug(f"\t\t_parse_feature -> {tokens}")
|
|
679
|
+
tokens = tokens.as_list()
|
|
680
|
+
role: str = tokens[1]
|
|
681
|
+
if tokens[2] == FuzzyDLKeyword.INTEGER:
|
|
682
|
+
kb.define_integer_concrete_feature(role, int(tokens[3]), int(tokens[4]))
|
|
683
|
+
elif tokens[2] == FuzzyDLKeyword.REAL:
|
|
684
|
+
kb.define_real_concrete_feature(role, float(tokens[3]), float(tokens[4]))
|
|
685
|
+
elif tokens[2] == FuzzyDLKeyword.BOOLEAN:
|
|
686
|
+
kb.define_boolean_concrete_feature(role)
|
|
687
|
+
elif tokens[2] == FuzzyDLKeyword.STRING:
|
|
688
|
+
kb.define_string_concrete_feature(role)
|
|
689
|
+
return pp.ParseResults(tokens)
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
def _parse_restrictions(kb: KnowledgeBase, tokens: pp.ParseResults) -> typing.Any:
|
|
693
|
+
if ConfigReader.DEBUG_PRINT:
|
|
694
|
+
Util.debug(f"\t\t_parse_restrictions -> {tokens}")
|
|
695
|
+
tokens = tokens.as_list()
|
|
696
|
+
if len(tokens) == 1:
|
|
697
|
+
if isinstance(tokens[0], (str, int, float)):
|
|
698
|
+
return FeatureFunction(tokens[0])
|
|
699
|
+
elif len(tokens) == 2 and isinstance(tokens[0], (int, float)):
|
|
700
|
+
return FeatureFunction(tokens[0], pp.ParseResults([tokens[1]]))
|
|
701
|
+
elif len(tokens) == 3:
|
|
702
|
+
if isinstance(tokens[0], (int, float)):
|
|
703
|
+
return FeatureFunction(tokens[0], FeatureFunction(tokens[2]))
|
|
704
|
+
if isinstance(tokens[0], str):
|
|
705
|
+
if "-" in tokens:
|
|
706
|
+
return FeatureFunction(
|
|
707
|
+
FeatureFunction(tokens[0]), FeatureFunction(tokens[2])
|
|
708
|
+
)
|
|
709
|
+
elif "+" in tokens:
|
|
710
|
+
return FeatureFunction(
|
|
711
|
+
FeatureFunction(list(map(FeatureFunction, tokens[::2])))
|
|
712
|
+
)
|
|
713
|
+
return pp.ParseResults(tokens)
|
|
714
|
+
|
|
715
|
+
|
|
716
|
+
def _parse_datatype_restriction(
|
|
717
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
718
|
+
) -> pp.ParseResults:
|
|
719
|
+
if ConfigReader.DEBUG_PRINT:
|
|
720
|
+
Util.debug(f"\t\t_parse_datatype_restriction -> {tokens}")
|
|
721
|
+
list_tokens = tokens.as_list()
|
|
722
|
+
role: str = list_tokens[1]
|
|
723
|
+
if role not in kb.concrete_features:
|
|
724
|
+
Util.error(f"Error: Feature {role} has not been defined.")
|
|
725
|
+
restriction_type: RestrictionType = RestrictionType.EXACT_VALUE
|
|
726
|
+
if list_tokens[0] == FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO:
|
|
727
|
+
restriction_type = RestrictionType.AT_MOST_VALUE
|
|
728
|
+
elif list_tokens[0] == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO:
|
|
729
|
+
restriction_type = RestrictionType.AT_LEAST_VALUE
|
|
730
|
+
if isinstance(list_tokens[2], str):
|
|
731
|
+
if tokens[2].get_name() == "string":
|
|
732
|
+
return pp.ParseResults(
|
|
733
|
+
[kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
|
|
734
|
+
)
|
|
735
|
+
else:
|
|
736
|
+
if kb.check_fuzzy_number_concept_exists(list_tokens[2]):
|
|
737
|
+
return pp.ParseResults(
|
|
738
|
+
[
|
|
739
|
+
kb.add_datatype_restriction(
|
|
740
|
+
restriction_type, kb.get_concept(list_tokens[2]), role
|
|
741
|
+
)
|
|
742
|
+
]
|
|
743
|
+
)
|
|
744
|
+
else:
|
|
745
|
+
v: Variable = Variable(list_tokens[2], VariableType.CONTINUOUS)
|
|
746
|
+
return pp.ParseResults(
|
|
747
|
+
[kb.add_datatype_restriction(restriction_type, v, role)]
|
|
748
|
+
)
|
|
749
|
+
elif isinstance(list_tokens[2], TriangularFuzzyNumber):
|
|
750
|
+
if not TriangularFuzzyNumber.has_defined_range():
|
|
751
|
+
Util.error(
|
|
752
|
+
"Error: The range of the fuzzy numbers has to be defined before being used."
|
|
753
|
+
)
|
|
754
|
+
if list_tokens[2].is_number():
|
|
755
|
+
return pp.ParseResults(
|
|
756
|
+
[
|
|
757
|
+
kb.add_datatype_restriction(
|
|
758
|
+
restriction_type, list_tokens[2].get_a(), role
|
|
759
|
+
)
|
|
760
|
+
]
|
|
761
|
+
)
|
|
762
|
+
else:
|
|
763
|
+
return pp.ParseResults(
|
|
764
|
+
[kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
|
|
765
|
+
)
|
|
766
|
+
elif isinstance(list_tokens[2], FeatureFunction):
|
|
767
|
+
return pp.ParseResults(
|
|
768
|
+
[kb.add_datatype_restriction(restriction_type, list_tokens[2], role)]
|
|
769
|
+
)
|
|
770
|
+
return tokens
|
|
771
|
+
|
|
772
|
+
|
|
773
|
+
def _parse_expression(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
774
|
+
if ConfigReader.DEBUG_PRINT:
|
|
775
|
+
Util.debug(f"\t\t_parse_expression -> {tokens}")
|
|
776
|
+
list_tokens: list = tokens.as_list()
|
|
777
|
+
if "+" in list_tokens and "*" in list_tokens:
|
|
778
|
+
list_tokens = [t for t in list_tokens if t not in ("+", "*")]
|
|
779
|
+
constants: list[int | float] = list_tokens[::2]
|
|
780
|
+
variables: list[int | float] = list_tokens[1::2]
|
|
781
|
+
expr: Expression = Expression(0)
|
|
782
|
+
for c, v in zip(constants, variables):
|
|
783
|
+
expr.add_term(Term(c, v))
|
|
784
|
+
return pp.ParseResults([expr])
|
|
785
|
+
return tokens
|
|
786
|
+
|
|
787
|
+
|
|
788
|
+
def _parse_inequation(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
789
|
+
if ConfigReader.DEBUG_PRINT:
|
|
790
|
+
Util.debug(f"\t\t_parse_inequation -> {tokens}")
|
|
791
|
+
list_tokens: list = tokens.as_list()
|
|
792
|
+
if isinstance(list_tokens[0], Expression):
|
|
793
|
+
operator: str = list_tokens[1]
|
|
794
|
+
constant: int | float = list_tokens[2]
|
|
795
|
+
expr: Expression = list_tokens[0] - constant
|
|
796
|
+
operator_type: InequalityType = (
|
|
797
|
+
InequalityType.EQUAL
|
|
798
|
+
if operator == FuzzyDLKeyword.EQUALS
|
|
799
|
+
else (
|
|
800
|
+
InequalityType.GREATER_THAN
|
|
801
|
+
if operator == FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO
|
|
802
|
+
else InequalityType.LESS_THAN
|
|
803
|
+
)
|
|
804
|
+
)
|
|
805
|
+
kb.milp.add_new_constraint(expr, operator_type)
|
|
806
|
+
return tokens
|
|
807
|
+
|
|
808
|
+
|
|
809
|
+
def _parse_constraints(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
810
|
+
if ConfigReader.DEBUG_PRINT:
|
|
811
|
+
Util.debug(f"\t\t_parse_constraints -> {tokens}")
|
|
812
|
+
list_tokens: list = tokens.as_list()
|
|
813
|
+
if list_tokens[0] == FuzzyDLKeyword.BINARY:
|
|
814
|
+
v: Variable = kb.milp.get_variable(list_tokens[1])
|
|
815
|
+
v.set_type(VariableType.BINARY)
|
|
816
|
+
elif list_tokens[0] == FuzzyDLKeyword.FREE:
|
|
817
|
+
v: Variable = kb.milp.get_variable(list_tokens[1])
|
|
818
|
+
v.set_type(VariableType.CONTINUOUS)
|
|
819
|
+
return tokens
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def _show_concrete_fillers(
|
|
823
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
824
|
+
) -> pp.ParseResults:
|
|
825
|
+
if ConfigReader.DEBUG_PRINT:
|
|
826
|
+
Util.debug(f"\t\t_show_concrete_fillers -> {tokens}")
|
|
827
|
+
list_tokens: list = tokens.as_list()
|
|
828
|
+
for role in list_tokens:
|
|
829
|
+
if role in kb.concrete_roles:
|
|
830
|
+
kb.milp.show_vars.add_concrete_filler_to_show(role)
|
|
831
|
+
else:
|
|
832
|
+
Util.error(
|
|
833
|
+
"Error: show-concrete-fillers can only be used with concrete roles."
|
|
834
|
+
)
|
|
835
|
+
return tokens
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def _show_concrete_fillers_for(
|
|
839
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
840
|
+
) -> pp.ParseResults:
|
|
841
|
+
if ConfigReader.DEBUG_PRINT:
|
|
842
|
+
Util.debug(f"\t\t_show_concrete_fillers_for -> {tokens}")
|
|
843
|
+
list_tokens: list = tokens.as_list()
|
|
844
|
+
ind_name: str = list_tokens[0]
|
|
845
|
+
for role in list_tokens[1:]:
|
|
846
|
+
if role in kb.concrete_roles:
|
|
847
|
+
kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name)
|
|
848
|
+
else:
|
|
849
|
+
Util.error(
|
|
850
|
+
"Error: show-concrete-fillers-for can only be used with concrete roles."
|
|
851
|
+
)
|
|
852
|
+
return tokens
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
def _show_concrete_instance_for(
|
|
856
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
857
|
+
) -> pp.ParseResults:
|
|
858
|
+
if ConfigReader.DEBUG_PRINT:
|
|
859
|
+
Util.debug(f"\t\t_show_concrete_instance_for -> {tokens}")
|
|
860
|
+
list_tokens: list = tokens.as_list()
|
|
861
|
+
ind_name: str = list_tokens[0]
|
|
862
|
+
role: str = list_tokens[1]
|
|
863
|
+
if role not in kb.concrete_roles:
|
|
864
|
+
Util.error(
|
|
865
|
+
"Error: show-concrete-instance-for can only be used with concrete roles."
|
|
866
|
+
)
|
|
867
|
+
ar: list[FuzzyConcreteConcept] = []
|
|
868
|
+
for c_name in list_tokens[2:]:
|
|
869
|
+
concept: Concept = kb.concrete_concepts.get(c_name)
|
|
870
|
+
if concept is None:
|
|
871
|
+
Util.error(f"Error: Concrete fuzzy concept {c_name} has not been defined.")
|
|
872
|
+
if concept.type not in (ConceptType.CONCRETE, ConceptType.FUZZY_NUMBER):
|
|
873
|
+
Util.error(f"Error: {c_name} is not a concrete fuzzy concept.")
|
|
874
|
+
ar.append(typing.cast(FuzzyConcreteConcept, concept))
|
|
875
|
+
kb.milp.show_vars.add_concrete_filler_to_show(role, ind_name, ar)
|
|
876
|
+
return tokens
|
|
877
|
+
|
|
878
|
+
|
|
879
|
+
def _show_abstract_fillers(
|
|
880
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
881
|
+
) -> pp.ParseResults:
|
|
882
|
+
if ConfigReader.DEBUG_PRINT:
|
|
883
|
+
Util.debug(f"\t\t_show_abstract_fillers -> {tokens}")
|
|
884
|
+
list_tokens: list = tokens.as_list()
|
|
885
|
+
for role in list_tokens:
|
|
886
|
+
if role in kb.concrete_roles:
|
|
887
|
+
Util.error(
|
|
888
|
+
"Error: show-abstract-fillers can only be used with abstract roles."
|
|
889
|
+
)
|
|
890
|
+
continue
|
|
891
|
+
kb.milp.show_vars.add_abstract_filler_to_show(role)
|
|
892
|
+
return tokens
|
|
893
|
+
|
|
894
|
+
|
|
895
|
+
def _show_abstract_fillers_for(
|
|
896
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
897
|
+
) -> pp.ParseResults:
|
|
898
|
+
if ConfigReader.DEBUG_PRINT:
|
|
899
|
+
Util.debug(f"\t\t_show_abstract_fillers_for -> {tokens}")
|
|
900
|
+
list_tokens: list = tokens.as_list()
|
|
901
|
+
ind_name: str = list_tokens[1:]
|
|
902
|
+
for role in list_tokens:
|
|
903
|
+
if role in kb.concrete_roles:
|
|
904
|
+
Util.error(
|
|
905
|
+
"Error: show-abstract-fillers-for can only be used with abstract roles."
|
|
906
|
+
)
|
|
907
|
+
kb.milp.show_vars.add_abstract_filler_to_show(role, ind_name)
|
|
908
|
+
return tokens
|
|
909
|
+
|
|
910
|
+
|
|
911
|
+
def _show_concepts(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
912
|
+
if ConfigReader.DEBUG_PRINT:
|
|
913
|
+
Util.debug(f"\t\t_show_concepts -> {tokens}")
|
|
914
|
+
list_tokens: list = tokens.as_list()
|
|
915
|
+
for ind_name in list_tokens:
|
|
916
|
+
kb.milp.show_vars.add_individual_to_show(ind_name)
|
|
917
|
+
return tokens
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
def _show_instances(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
921
|
+
if ConfigReader.DEBUG_PRINT:
|
|
922
|
+
Util.debug(f"\t\t_show_instances -> {tokens}")
|
|
923
|
+
list_tokens: list = tokens.as_list()
|
|
924
|
+
for concept in list_tokens:
|
|
925
|
+
concept: Concept = _to_concept(kb, concept)
|
|
926
|
+
kb.milp.show_vars.add_concept_to_show(str(concept))
|
|
927
|
+
return tokens
|
|
928
|
+
|
|
929
|
+
|
|
930
|
+
def _show_variables(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
931
|
+
if ConfigReader.DEBUG_PRINT:
|
|
932
|
+
Util.debug(f"\t\t_show_variables -> {tokens}")
|
|
933
|
+
list_tokens: list = tokens.as_list()
|
|
934
|
+
for variable_name in list_tokens:
|
|
935
|
+
var: Variable = kb.milp.get_variable(variable_name)
|
|
936
|
+
kb.milp.show_vars.add_variable(var, str(var))
|
|
937
|
+
return tokens
|
|
938
|
+
|
|
939
|
+
|
|
940
|
+
def _show_languages(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
941
|
+
if ConfigReader.DEBUG_PRINT:
|
|
942
|
+
Util.debug(f"\t\t_show_languages -> {tokens}")
|
|
943
|
+
kb.show_language = True
|
|
944
|
+
return tokens
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
def _parse_crisp_declarations(
|
|
948
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
949
|
+
) -> pp.ParseResults:
|
|
950
|
+
if ConfigReader.DEBUG_PRINT:
|
|
951
|
+
Util.debug(f"\t\t_parse_crisp_declarations -> {tokens}")
|
|
952
|
+
list_tokens: list = tokens.as_list()
|
|
953
|
+
if list_tokens[0] == FuzzyDLKeyword.CRISP_CONCEPT:
|
|
954
|
+
for concept in list_tokens[1:]:
|
|
955
|
+
concept: Concept = _to_concept(kb, concept)
|
|
956
|
+
kb.set_crisp_concept(concept)
|
|
957
|
+
elif list_tokens[0] == FuzzyDLKeyword.CRISP_ROLE:
|
|
958
|
+
for role in list_tokens[1:]:
|
|
959
|
+
kb.set_crisp_role(role)
|
|
960
|
+
return tokens
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
def _parse_fuzzy_similarity(
|
|
964
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
965
|
+
) -> pp.ParseResults:
|
|
966
|
+
if ConfigReader.DEBUG_PRINT:
|
|
967
|
+
Util.debug(f"\t\t_parse_fuzzy_similarity -> {tokens}")
|
|
968
|
+
list_tokens: list = tokens.as_list()
|
|
969
|
+
kb.add_similarity_relation(list_tokens[0])
|
|
970
|
+
return tokens
|
|
971
|
+
|
|
972
|
+
|
|
973
|
+
def _parse_fuzzy_equivalence(
|
|
974
|
+
kb: KnowledgeBase, tokens: pp.ParseResults
|
|
975
|
+
) -> pp.ParseResults:
|
|
976
|
+
if ConfigReader.DEBUG_PRINT:
|
|
977
|
+
Util.debug(f"\t\t_parse_fuzzy_equivalence -> {tokens}")
|
|
978
|
+
list_tokens: list = tokens.as_list()
|
|
979
|
+
kb.add_equivalence_relation(list_tokens[0])
|
|
980
|
+
return tokens
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
def _parse_degree(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
984
|
+
if ConfigReader.DEBUG_PRINT:
|
|
985
|
+
Util.debug(f"\t\t_parse_degree -> {tokens}")
|
|
986
|
+
|
|
987
|
+
list_tokens: list = tokens.as_list()
|
|
988
|
+
if isinstance(list_tokens[0], (int, float)):
|
|
989
|
+
return pp.ParseResults([DegreeNumeric.get_degree(float(list_tokens[0]))])
|
|
990
|
+
elif isinstance(list_tokens[0], Expression):
|
|
991
|
+
return pp.ParseResults([DegreeExpression.get_degree(list_tokens[0])])
|
|
992
|
+
elif isinstance(list_tokens[0], str):
|
|
993
|
+
tc: typing.Optional[float] = kb.get_truth_constants(list_tokens[0])
|
|
994
|
+
if tc is not None:
|
|
995
|
+
return pp.ParseResults([DegreeNumeric.get_degree(float(tc))])
|
|
996
|
+
else:
|
|
997
|
+
return pp.ParseResults(
|
|
998
|
+
[DegreeVariable.get_degree(kb.milp.get_variable(list_tokens[0]))]
|
|
999
|
+
)
|
|
1000
|
+
return tokens
|
|
1001
|
+
|
|
1002
|
+
|
|
1003
|
+
def _parse_axioms(kb: KnowledgeBase, tokens: pp.ParseResults) -> pp.ParseResults:
|
|
1004
|
+
if ConfigReader.DEBUG_PRINT:
|
|
1005
|
+
Util.debug(f"\t\t_parse_axioms -> {tokens}")
|
|
1006
|
+
|
|
1007
|
+
list_tokens: list = tokens.as_list()[0]
|
|
1008
|
+
if list_tokens[0] == FuzzyDLKeyword.INSTANCE:
|
|
1009
|
+
a: Individual = kb.get_individual(list_tokens[1])
|
|
1010
|
+
c: Concept = _to_concept(kb, list_tokens[2])
|
|
1011
|
+
d: Degree = (
|
|
1012
|
+
list_tokens[3] if len(list_tokens) > 3 else DegreeNumeric.get_degree(1.0)
|
|
1013
|
+
)
|
|
1014
|
+
kb.add_assertion(a, c, d)
|
|
1015
|
+
elif list_tokens[0] == FuzzyDLKeyword.RELATED:
|
|
1016
|
+
a: Individual = kb.get_individual(list_tokens[1])
|
|
1017
|
+
b: Individual = kb.get_individual(list_tokens[2])
|
|
1018
|
+
role: str = list_tokens[3]
|
|
1019
|
+
d: Degree = (
|
|
1020
|
+
list_tokens[4] if len(list_tokens) > 4 else DegreeNumeric.get_degree(1.0)
|
|
1021
|
+
)
|
|
1022
|
+
if role in kb.concrete_roles:
|
|
1023
|
+
Util.error(f"Error: Role {role} cannot be concrete and abstract.")
|
|
1024
|
+
kb.add_relation(a, role, b, d)
|
|
1025
|
+
elif list_tokens[0] in (
|
|
1026
|
+
FuzzyDLKeyword.GOEDEL_IMPLIES,
|
|
1027
|
+
FuzzyDLKeyword.LUKASIEWICZ_IMPLIES,
|
|
1028
|
+
FuzzyDLKeyword.KLEENE_DIENES_IMPLIES,
|
|
1029
|
+
FuzzyDLKeyword.IMPLIES,
|
|
1030
|
+
):
|
|
1031
|
+
c1: Concept = _to_concept(kb, list_tokens[1])
|
|
1032
|
+
c2: Concept = _to_concept(kb, list_tokens[2])
|
|
1033
|
+
d: Degree = (
|
|
1034
|
+
list_tokens[3] if len(list_tokens) > 3 else DegreeNumeric.get_degree(1.0)
|
|
1035
|
+
)
|
|
1036
|
+
if list_tokens[0] == FuzzyDLKeyword.IMPLIES:
|
|
1037
|
+
kb.implies(c1, c2, d)
|
|
1038
|
+
elif list_tokens[0] == FuzzyDLKeyword.GOEDEL_IMPLIES:
|
|
1039
|
+
kb.goedel_implies(c1, c2, d)
|
|
1040
|
+
elif list_tokens[0] == FuzzyDLKeyword.LUKASIEWICZ_IMPLIES:
|
|
1041
|
+
kb.lukasiewicz_implies(c1, c2, d)
|
|
1042
|
+
elif list_tokens[0] == FuzzyDLKeyword.KLEENE_DIENES_IMPLIES:
|
|
1043
|
+
kb.kleene_dienes_implies(c1, c2, d)
|
|
1044
|
+
elif list_tokens[0] == FuzzyDLKeyword.ZADEH_IMPLIES:
|
|
1045
|
+
c1: Concept = _to_concept(kb, list_tokens[1])
|
|
1046
|
+
c2: Concept = _to_concept(kb, list_tokens[2])
|
|
1047
|
+
kb.zadeh_implies(c1, c2)
|
|
1048
|
+
elif list_tokens[0] == FuzzyDLKeyword.DEFINE_CONCEPT:
|
|
1049
|
+
name: str = list_tokens[1]
|
|
1050
|
+
c: Concept = _to_concept(kb, list_tokens[2])
|
|
1051
|
+
kb.define_concept(name, c)
|
|
1052
|
+
elif list_tokens[0] == FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT:
|
|
1053
|
+
name: str = list_tokens[1]
|
|
1054
|
+
c: Concept = _to_concept(kb, list_tokens[2])
|
|
1055
|
+
kb.define_atomic_concept(name, c, LogicOperatorType.ZADEH, 1.0)
|
|
1056
|
+
elif list_tokens[0] == FuzzyDLKeyword.EQUIVALENT_CONCEPTS:
|
|
1057
|
+
c1: Concept = _to_concept(kb, list_tokens[1])
|
|
1058
|
+
c2: Concept = _to_concept(kb, list_tokens[2])
|
|
1059
|
+
kb.define_equivalent_concepts(c1, c2)
|
|
1060
|
+
elif list_tokens[0] == FuzzyDLKeyword.DISJOINT_UNION:
|
|
1061
|
+
concepts: list[str] = [str(_to_concept(kb, t)) for t in list_tokens[1:]]
|
|
1062
|
+
kb.add_disjoint_union_concept(concepts)
|
|
1063
|
+
elif list_tokens[0] == FuzzyDLKeyword.DISJOINT:
|
|
1064
|
+
concepts: list[Concept] = [_to_concept(kb, t) for t in list_tokens[1:]]
|
|
1065
|
+
kb.add_concepts_disjoint(concepts)
|
|
1066
|
+
elif list_tokens[0] in (FuzzyDLKeyword.RANGE, FuzzyDLKeyword.DOMAIN):
|
|
1067
|
+
role: str = list_tokens[1]
|
|
1068
|
+
concept: Concept = _to_concept(kb, list_tokens[2])
|
|
1069
|
+
if list_tokens[0] == FuzzyDLKeyword.RANGE:
|
|
1070
|
+
kb.check_role(role, concept)
|
|
1071
|
+
kb.role_range(role, concept)
|
|
1072
|
+
else:
|
|
1073
|
+
kb.role_domain(role, concept)
|
|
1074
|
+
elif list_tokens[0] == FuzzyDLKeyword.FUNCTIONAL:
|
|
1075
|
+
role: str = list_tokens[1]
|
|
1076
|
+
kb.role_is_functional(role)
|
|
1077
|
+
elif list_tokens[0] == FuzzyDLKeyword.TRANSITIVE:
|
|
1078
|
+
role: str = list_tokens[1]
|
|
1079
|
+
kb.role_is_transitive(role)
|
|
1080
|
+
elif list_tokens[0] == FuzzyDLKeyword.SYMMETRIC:
|
|
1081
|
+
role: str = list_tokens[1]
|
|
1082
|
+
kb.role_is_symmetric(role)
|
|
1083
|
+
elif list_tokens[0] == FuzzyDLKeyword.REFLEXIVE:
|
|
1084
|
+
role: str = list_tokens[1]
|
|
1085
|
+
kb.role_is_reflexive(role)
|
|
1086
|
+
elif list_tokens[0] == FuzzyDLKeyword.INVERSE_FUNCTIONAL:
|
|
1087
|
+
role: str = list_tokens[1]
|
|
1088
|
+
if role in kb.concrete_roles:
|
|
1089
|
+
Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
|
|
1090
|
+
kb.role_is_inverse_functional(role)
|
|
1091
|
+
elif list_tokens[0] == FuzzyDLKeyword.INVERSE:
|
|
1092
|
+
role: str = list_tokens[1]
|
|
1093
|
+
inv_role: str = list_tokens[2]
|
|
1094
|
+
if role in kb.concrete_roles:
|
|
1095
|
+
Util.error(f"Error: Concrete role {role} cannot have an inverse role.")
|
|
1096
|
+
elif inv_role in kb.concrete_roles:
|
|
1097
|
+
Util.error(f"Error: Concrete role {inv_role} cannot have an inverse role.")
|
|
1098
|
+
else:
|
|
1099
|
+
kb.add_inverse_roles(role, inv_role)
|
|
1100
|
+
elif list_tokens[0] == FuzzyDLKeyword.IMPLIES_ROLE:
|
|
1101
|
+
role_c: str = list_tokens[1]
|
|
1102
|
+
role_p: str = list_tokens[2]
|
|
1103
|
+
d: float = list_tokens[3] if len(list_tokens) > 3 else 1.0
|
|
1104
|
+
kb.role_implies(role_c, role_p, d)
|
|
1105
|
+
return tokens
|
|
1106
|
+
|
|
1107
|
+
|
|
1108
|
+
def _parse_queries(
|
|
1109
|
+
kb: KnowledgeBase, queries_list: list[Query], tokens: pp.ParseResults
|
|
1110
|
+
) -> pp.ParseResults:
|
|
1111
|
+
if ConfigReader.DEBUG_PRINT:
|
|
1112
|
+
Util.debug(f"\t\t_parse_queries -> {tokens}")
|
|
1113
|
+
|
|
1114
|
+
list_tokens: list[str] = tokens.as_list()[0]
|
|
1115
|
+
|
|
1116
|
+
if list_tokens[0] == FuzzyDLKeyword.ALL_INSTANCES_QUERY:
|
|
1117
|
+
queries_list.append(AllInstancesQuery(list_tokens[1]))
|
|
1118
|
+
elif list_tokens[0] == FuzzyDLKeyword.SAT_QUERY:
|
|
1119
|
+
queries_list.append(KbSatisfiableQuery())
|
|
1120
|
+
elif list_tokens[0] in (FuzzyDLKeyword.MIN_SAT_QUERY, FuzzyDLKeyword.MAX_SAT_QUERY):
|
|
1121
|
+
_class: Query = (
|
|
1122
|
+
MinSatisfiableQuery
|
|
1123
|
+
if list_tokens[0] == FuzzyDLKeyword.MIN_SAT_QUERY
|
|
1124
|
+
else MaxSatisfiableQuery
|
|
1125
|
+
)
|
|
1126
|
+
c: Concept = _to_concept(kb, list_tokens[1])
|
|
1127
|
+
if len(list_tokens) > 2:
|
|
1128
|
+
queries_list.append(_class(c, kb.get_individual(list_tokens[2])))
|
|
1129
|
+
else:
|
|
1130
|
+
queries_list.append(_class(c))
|
|
1131
|
+
elif list_tokens[0] in (
|
|
1132
|
+
FuzzyDLKeyword.MAX_INSTANCE_QUERY,
|
|
1133
|
+
FuzzyDLKeyword.MIN_INSTANCE_QUERY,
|
|
1134
|
+
):
|
|
1135
|
+
_class: Query = (
|
|
1136
|
+
MaxInstanceQuery
|
|
1137
|
+
if list_tokens[0] == FuzzyDLKeyword.MAX_INSTANCE_QUERY
|
|
1138
|
+
else MinInstanceQuery
|
|
1139
|
+
)
|
|
1140
|
+
a: Individual = kb.get_individual(list_tokens[1])
|
|
1141
|
+
c: Concept = _to_concept(kb, list_tokens[2])
|
|
1142
|
+
queries_list.append(_class(c, a))
|
|
1143
|
+
elif list_tokens[0] in (
|
|
1144
|
+
FuzzyDLKeyword.MAX_SUBS_QUERY,
|
|
1145
|
+
FuzzyDLKeyword.MIN_SUBS_QUERY,
|
|
1146
|
+
FuzzyDLKeyword.MAX_G_SUBS_QUERY,
|
|
1147
|
+
FuzzyDLKeyword.MIN_G_SUBS_QUERY,
|
|
1148
|
+
FuzzyDLKeyword.MAX_L_SUBS_QUERY,
|
|
1149
|
+
FuzzyDLKeyword.MIN_L_SUBS_QUERY,
|
|
1150
|
+
FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
|
|
1151
|
+
FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
|
|
1152
|
+
):
|
|
1153
|
+
_class = (
|
|
1154
|
+
MaxSubsumesQuery
|
|
1155
|
+
if list_tokens[0].lower().startswith("max")
|
|
1156
|
+
else MinSubsumesQuery
|
|
1157
|
+
)
|
|
1158
|
+
c1: Concept = _to_concept(kb, list_tokens[1])
|
|
1159
|
+
c2: Concept = _to_concept(kb, list_tokens[2])
|
|
1160
|
+
if list_tokens[0] in (
|
|
1161
|
+
FuzzyDLKeyword.MAX_SUBS_QUERY,
|
|
1162
|
+
FuzzyDLKeyword.MIN_SUBS_QUERY,
|
|
1163
|
+
):
|
|
1164
|
+
if kb.get_logic() == FuzzyLogic.LUKASIEWICZ:
|
|
1165
|
+
queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
|
|
1166
|
+
else:
|
|
1167
|
+
queries_list.append(_class(c1, c2, LogicOperatorType.ZADEH))
|
|
1168
|
+
elif list_tokens[0] in (
|
|
1169
|
+
FuzzyDLKeyword.MAX_G_SUBS_QUERY,
|
|
1170
|
+
FuzzyDLKeyword.MIN_G_SUBS_QUERY,
|
|
1171
|
+
):
|
|
1172
|
+
queries_list.append(_class(c1, c2, LogicOperatorType.GOEDEL))
|
|
1173
|
+
elif list_tokens[0] in (
|
|
1174
|
+
FuzzyDLKeyword.MAX_L_SUBS_QUERY,
|
|
1175
|
+
FuzzyDLKeyword.MIN_L_SUBS_QUERY,
|
|
1176
|
+
):
|
|
1177
|
+
queries_list.append(_class(c1, c2, LogicOperatorType.LUKASIEWICZ))
|
|
1178
|
+
elif list_tokens[0] in (
|
|
1179
|
+
FuzzyDLKeyword.MAX_KD_SUBS_QUERY,
|
|
1180
|
+
FuzzyDLKeyword.MIN_KD_SUBS_QUERY,
|
|
1181
|
+
):
|
|
1182
|
+
queries_list.append(_class(c1, c2, LogicOperatorType.KLEENE_DIENES))
|
|
1183
|
+
elif list_tokens[0] in (
|
|
1184
|
+
FuzzyDLKeyword.MAX_RELATED_QUERY,
|
|
1185
|
+
FuzzyDLKeyword.MIN_RELATED_QUERY,
|
|
1186
|
+
):
|
|
1187
|
+
a: Individual = kb.get_individual(list_tokens[1])
|
|
1188
|
+
b: Individual = kb.get_individual(list_tokens[2])
|
|
1189
|
+
role: str = list_tokens[3]
|
|
1190
|
+
if role in kb.concrete_roles:
|
|
1191
|
+
Util.error(f"Error: Role {role} cannot be concrete and abstract.")
|
|
1192
|
+
kb.abstract_roles.add(role)
|
|
1193
|
+
if list_tokens[0] == FuzzyDLKeyword.MAX_RELATED_QUERY:
|
|
1194
|
+
queries_list.append(MaxRelatedQuery(a, b, role))
|
|
1195
|
+
else:
|
|
1196
|
+
queries_list.append(MinRelatedQuery(a, b, role))
|
|
1197
|
+
elif list_tokens[0] == FuzzyDLKeyword.MAX_VAR_QUERY:
|
|
1198
|
+
queries_list.append(MaxQuery(list_tokens[1]))
|
|
1199
|
+
elif list_tokens[0] == FuzzyDLKeyword.MIN_VAR_QUERY:
|
|
1200
|
+
queries_list.append(MinQuery(list_tokens[1]))
|
|
1201
|
+
elif list_tokens[0] in (
|
|
1202
|
+
FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY,
|
|
1203
|
+
FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY,
|
|
1204
|
+
FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY,
|
|
1205
|
+
):
|
|
1206
|
+
c: Concept = _to_concept(kb, list_tokens[1])
|
|
1207
|
+
a: Individual = kb.get_individual(list_tokens[2])
|
|
1208
|
+
role: str = list_tokens[3]
|
|
1209
|
+
if kb.concrete_features.get(role) is None:
|
|
1210
|
+
Util.error(f"Error: Feature {role} has not been defined.")
|
|
1211
|
+
if list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY:
|
|
1212
|
+
queries_list.append(LomDefuzzifyQuery(c, a, role))
|
|
1213
|
+
elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY:
|
|
1214
|
+
queries_list.append(SomDefuzzifyQuery(c, a, role))
|
|
1215
|
+
elif list_tokens[0] == FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY:
|
|
1216
|
+
queries_list.append(MomDefuzzifyQuery(c, a, role))
|
|
1217
|
+
elif list_tokens[0] == FuzzyDLKeyword.BNP_QUERY:
|
|
1218
|
+
if not TriangularFuzzyNumber.has_defined_range():
|
|
1219
|
+
Util.error(
|
|
1220
|
+
"Error: The range of the fuzzy numbers has to be defined before being used."
|
|
1221
|
+
)
|
|
1222
|
+
queries_list.append(BnpQuery(list_tokens[1]))
|
|
1223
|
+
return tokens
|
|
1224
|
+
|
|
1225
|
+
|
|
1226
|
+
class DLParser(object):
|
|
1227
|
+
|
|
1228
|
+
@staticmethod
|
|
1229
|
+
def get_grammatics(
|
|
1230
|
+
kb: KnowledgeBase, queries_list: list[Query]
|
|
1231
|
+
) -> pp.ParserElement:
|
|
1232
|
+
"""
|
|
1233
|
+
This function generate the grammatics to parse the predicate wih formula "formula".
|
|
1234
|
+
|
|
1235
|
+
Parameters
|
|
1236
|
+
---------------------------
|
|
1237
|
+
formula := The predicate formula used for the parsing.
|
|
1238
|
+
|
|
1239
|
+
Returns
|
|
1240
|
+
---------------------------
|
|
1241
|
+
The parsed result given by pyparsing.
|
|
1242
|
+
"""
|
|
1243
|
+
pp.ParserElement.enable_left_recursion(force=True)
|
|
1244
|
+
|
|
1245
|
+
lbrace = pp.Literal("(").set_results_name("lbrace").suppress()
|
|
1246
|
+
rbrace = pp.Literal(")").set_results_name("rbrace").suppress()
|
|
1247
|
+
comment = pp.one_of(["#", "%"]).set_results_name("comment").suppress()
|
|
1248
|
+
any_not_newline = (
|
|
1249
|
+
pp.Regex("[^\n]+").set_results_name("any_not_newline").suppress()
|
|
1250
|
+
)
|
|
1251
|
+
|
|
1252
|
+
digits = pp.Word(pp.nums)
|
|
1253
|
+
numbers = (
|
|
1254
|
+
pp.Combine(pp.Opt(pp.one_of(["+", "-"])) + digits + pp.Opt("." + digits))
|
|
1255
|
+
.set_results_name("number", list_all_matches=True)
|
|
1256
|
+
.set_parse_action(_to_number)
|
|
1257
|
+
)
|
|
1258
|
+
|
|
1259
|
+
simple_string = pp.Word(pp.alphas + "_", pp.alphanums + "_'").set_results_name(
|
|
1260
|
+
"string", list_all_matches=True
|
|
1261
|
+
) # pp.Regex(r"[a-zA-Z_][a-zA-Z0-9_]*")
|
|
1262
|
+
strings = (
|
|
1263
|
+
pp.Opt(pp.one_of(['"', "'"])).suppress()
|
|
1264
|
+
+ simple_string.set_results_name("string", list_all_matches=True)
|
|
1265
|
+
+ pp.Opt(pp.one_of(['"', "'"])).suppress()
|
|
1266
|
+
)
|
|
1267
|
+
variables = (
|
|
1268
|
+
strings | simple_string.set_results_name("variable", list_all_matches=True)
|
|
1269
|
+
).set_results_name("variables", list_all_matches=True)
|
|
1270
|
+
|
|
1271
|
+
fuzzy_logic = (
|
|
1272
|
+
(
|
|
1273
|
+
lbrace
|
|
1274
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_LOGIC.get_value().suppress()
|
|
1275
|
+
+ (
|
|
1276
|
+
FuzzyDLKeyword.LUKASIEWICZ.get_value()
|
|
1277
|
+
| FuzzyDLKeyword.ZADEH.get_value()
|
|
1278
|
+
| FuzzyDLKeyword.CLASSICAL.get_value()
|
|
1279
|
+
).set_results_name("fuzzy_logic")
|
|
1280
|
+
+ rbrace
|
|
1281
|
+
)
|
|
1282
|
+
.set_results_name("fuzzy_logics", list_all_matches=True)
|
|
1283
|
+
.add_parse_action(partial(_fuzzy_logic_parser, kb))
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
comment_line = (comment + any_not_newline).set_results_name(
|
|
1287
|
+
"comments", list_all_matches=True
|
|
1288
|
+
)
|
|
1289
|
+
|
|
1290
|
+
concept = pp.Forward()
|
|
1291
|
+
|
|
1292
|
+
weighted_concept_part = (
|
|
1293
|
+
(lbrace + numbers + concept + rbrace)
|
|
1294
|
+
.set_results_name("simple_weighted_concepts_single", list_all_matches=True)
|
|
1295
|
+
.set_parse_action(partial(_parse_weighted_concept_simple, kb))
|
|
1296
|
+
)
|
|
1297
|
+
|
|
1298
|
+
simple_fuzzy_number = (
|
|
1299
|
+
(variables | lbrace + numbers[3] + rbrace | numbers)
|
|
1300
|
+
.set_results_name("simple_fuzzy_numbers", list_all_matches=True)
|
|
1301
|
+
.set_parse_action(partial(_create_fuzzy_number, kb))
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
fuzzy_number_expr = pp.Forward()
|
|
1305
|
+
fuzzy_number_expr <<= (
|
|
1306
|
+
simple_fuzzy_number
|
|
1307
|
+
| lbrace
|
|
1308
|
+
+ pp.one_of(
|
|
1309
|
+
[
|
|
1310
|
+
FuzzyDLKeyword.FEATURE_SUM.get_name(),
|
|
1311
|
+
FuzzyDLKeyword.FEATURE_MUL.get_name(),
|
|
1312
|
+
]
|
|
1313
|
+
)
|
|
1314
|
+
+ pp.OneOrMore(fuzzy_number_expr)
|
|
1315
|
+
+ rbrace
|
|
1316
|
+
| lbrace
|
|
1317
|
+
+ pp.one_of(
|
|
1318
|
+
[
|
|
1319
|
+
FuzzyDLKeyword.FEATURE_DIV.get_name(),
|
|
1320
|
+
FuzzyDLKeyword.FEATURE_SUB.get_name(),
|
|
1321
|
+
]
|
|
1322
|
+
)
|
|
1323
|
+
+ fuzzy_number_expr[2]
|
|
1324
|
+
+ rbrace
|
|
1325
|
+
).set_results_name("fuzzy_number_expressions", list_all_matches=True)
|
|
1326
|
+
|
|
1327
|
+
fuzzy_numbers = (
|
|
1328
|
+
(
|
|
1329
|
+
lbrace
|
|
1330
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_NUMBER.get_value().suppress()
|
|
1331
|
+
+ variables
|
|
1332
|
+
+ fuzzy_number_expr
|
|
1333
|
+
+ rbrace
|
|
1334
|
+
)
|
|
1335
|
+
.set_results_name("fuzzy_numbers", list_all_matches=True)
|
|
1336
|
+
.set_parse_action(partial(_set_fuzzy_number, kb))
|
|
1337
|
+
)
|
|
1338
|
+
|
|
1339
|
+
datatype_restriction_function = (
|
|
1340
|
+
(
|
|
1341
|
+
variables
|
|
1342
|
+
| numbers
|
|
1343
|
+
| numbers + pp.Opt(FuzzyDLKeyword.MUL.get_value()) + variables
|
|
1344
|
+
| variables + FuzzyDLKeyword.SUB.get_value() + variables
|
|
1345
|
+
| pp.DelimitedList(variables, delim=FuzzyDLKeyword.SUM.get_name())
|
|
1346
|
+
)
|
|
1347
|
+
.set_results_name("restrictions", list_all_matches=True)
|
|
1348
|
+
.set_parse_action(partial(_parse_restrictions, kb))
|
|
1349
|
+
)
|
|
1350
|
+
|
|
1351
|
+
datatype_restrictions = (
|
|
1352
|
+
(
|
|
1353
|
+
lbrace
|
|
1354
|
+
+ pp.one_of(
|
|
1355
|
+
[
|
|
1356
|
+
FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
|
|
1357
|
+
FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
|
|
1358
|
+
FuzzyDLKeyword.EQUALS.get_name(),
|
|
1359
|
+
]
|
|
1360
|
+
)
|
|
1361
|
+
+ variables
|
|
1362
|
+
+ (variables | datatype_restriction_function | fuzzy_number_expr)
|
|
1363
|
+
+ rbrace
|
|
1364
|
+
)
|
|
1365
|
+
.set_results_name("datatype_restrictions", list_all_matches=True)
|
|
1366
|
+
.set_parse_action(partial(_parse_datatype_restriction, kb))
|
|
1367
|
+
)
|
|
1368
|
+
|
|
1369
|
+
concept <<= (
|
|
1370
|
+
(
|
|
1371
|
+
variables
|
|
1372
|
+
| FuzzyDLKeyword.TOP.get_value()
|
|
1373
|
+
| FuzzyDLKeyword.BOTTOM.get_value()
|
|
1374
|
+
)
|
|
1375
|
+
.set_results_name("truth_constants", list_all_matches=True)
|
|
1376
|
+
.set_parse_action(partial(_to_top_bottom_concept, kb))
|
|
1377
|
+
| datatype_restrictions.set_results_name(
|
|
1378
|
+
"restriction_concepts", list_all_matches=True
|
|
1379
|
+
)
|
|
1380
|
+
| weighted_concept_part.set_results_name(
|
|
1381
|
+
"simple_weighted_concept", list_all_matches=True
|
|
1382
|
+
)
|
|
1383
|
+
| lbrace
|
|
1384
|
+
+ (
|
|
1385
|
+
(
|
|
1386
|
+
(
|
|
1387
|
+
pp.one_of(
|
|
1388
|
+
[
|
|
1389
|
+
FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
|
|
1390
|
+
FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
|
|
1391
|
+
]
|
|
1392
|
+
)
|
|
1393
|
+
+ (variables | numbers)
|
|
1394
|
+
+ concept
|
|
1395
|
+
)
|
|
1396
|
+
.set_results_name("threshold_concepts", list_all_matches=True)
|
|
1397
|
+
.set_parse_action(partial(_parse_threshold_concept, kb))
|
|
1398
|
+
| (
|
|
1399
|
+
pp.one_of(
|
|
1400
|
+
[
|
|
1401
|
+
FuzzyDLKeyword.AND.get_name(),
|
|
1402
|
+
FuzzyDLKeyword.GOEDEL_AND.get_name(),
|
|
1403
|
+
FuzzyDLKeyword.LUKASIEWICZ_AND.get_name(),
|
|
1404
|
+
FuzzyDLKeyword.OR.get_name(),
|
|
1405
|
+
FuzzyDLKeyword.GOEDEL_OR.get_name(),
|
|
1406
|
+
FuzzyDLKeyword.LUKASIEWICZ_OR.get_name(),
|
|
1407
|
+
FuzzyDLKeyword.IMPLIES.get_name(),
|
|
1408
|
+
FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
|
|
1409
|
+
FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
|
|
1410
|
+
FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
|
|
1411
|
+
]
|
|
1412
|
+
)
|
|
1413
|
+
+ concept[2, ...]
|
|
1414
|
+
).set_results_name("implies_concepts", list_all_matches=True)
|
|
1415
|
+
| (
|
|
1416
|
+
FuzzyDLKeyword.SOME.get_value()
|
|
1417
|
+
+ variables
|
|
1418
|
+
+ (variables | concept)
|
|
1419
|
+
).set_results_name("some_concepts", list_all_matches=True)
|
|
1420
|
+
| (
|
|
1421
|
+
FuzzyDLKeyword.HAS_VALUE.get_value() + variables + variables
|
|
1422
|
+
).set_results_name("has_value_concepts", list_all_matches=True)
|
|
1423
|
+
| pp.one_of(
|
|
1424
|
+
[
|
|
1425
|
+
FuzzyDLKeyword.ALL.get_name(),
|
|
1426
|
+
FuzzyDLKeyword.TIGHT_UPPER_APPROXIMATION.get_name(),
|
|
1427
|
+
FuzzyDLKeyword.LOOSE_UPPER_APPROXIMATION.get_name(),
|
|
1428
|
+
FuzzyDLKeyword.UPPER_APPROXIMATION.get_name(),
|
|
1429
|
+
FuzzyDLKeyword.TIGHT_LOWER_APPROXIMATION.get_name(),
|
|
1430
|
+
FuzzyDLKeyword.LOOSE_LOWER_APPROXIMATION.get_name(),
|
|
1431
|
+
FuzzyDLKeyword.LOWER_APPROXIMATION.get_name(),
|
|
1432
|
+
]
|
|
1433
|
+
)
|
|
1434
|
+
+ variables
|
|
1435
|
+
+ concept
|
|
1436
|
+
)
|
|
1437
|
+
.set_results_name("binary_concepts", list_all_matches=True)
|
|
1438
|
+
.set_parse_action(partial(_parse_binary_concept, kb))
|
|
1439
|
+
| (
|
|
1440
|
+
FuzzyDLKeyword.NOT.get_value() + concept
|
|
1441
|
+
| FuzzyDLKeyword.SELF.get_value() + variables
|
|
1442
|
+
)
|
|
1443
|
+
.set_results_name("unary_concepts", list_all_matches=True)
|
|
1444
|
+
.set_parse_action(partial(_parse_unary_concept, kb))
|
|
1445
|
+
| (variables + concept)
|
|
1446
|
+
.set_results_name("modifier_concepts", list_all_matches=True)
|
|
1447
|
+
.set_parse_action(partial(_parse_modifier_concept, kb))
|
|
1448
|
+
| (
|
|
1449
|
+
pp.one_of(
|
|
1450
|
+
[
|
|
1451
|
+
FuzzyDLKeyword.W_SUM_ZERO.get_name(),
|
|
1452
|
+
FuzzyDLKeyword.W_SUM.get_name(),
|
|
1453
|
+
FuzzyDLKeyword.W_MAX.get_name(),
|
|
1454
|
+
FuzzyDLKeyword.W_MIN.get_name(),
|
|
1455
|
+
]
|
|
1456
|
+
)
|
|
1457
|
+
+ pp.OneOrMore(weighted_concept_part)
|
|
1458
|
+
)
|
|
1459
|
+
.set_results_name("weighted_concepts", list_all_matches=True)
|
|
1460
|
+
.set_parse_action(partial(_parse_weighted_concept, kb))
|
|
1461
|
+
| (
|
|
1462
|
+
FuzzyDLKeyword.Q_OWA.get_value().suppress()
|
|
1463
|
+
+ variables
|
|
1464
|
+
+ pp.OneOrMore(concept)
|
|
1465
|
+
)
|
|
1466
|
+
.set_results_name("q_owas", list_all_matches=True)
|
|
1467
|
+
.set_parse_action(partial(_parse_q_owa_concept, kb))
|
|
1468
|
+
| (
|
|
1469
|
+
pp.one_of(
|
|
1470
|
+
[
|
|
1471
|
+
FuzzyDLKeyword.OWA.get_name(),
|
|
1472
|
+
FuzzyDLKeyword.CHOQUET.get_name(),
|
|
1473
|
+
FuzzyDLKeyword.QUASI_SUGENO.get_name(),
|
|
1474
|
+
FuzzyDLKeyword.SUGENO.get_name(),
|
|
1475
|
+
]
|
|
1476
|
+
)
|
|
1477
|
+
+ lbrace
|
|
1478
|
+
+ pp.OneOrMore(numbers)
|
|
1479
|
+
+ rbrace
|
|
1480
|
+
+ lbrace
|
|
1481
|
+
+ pp.OneOrMore(concept)
|
|
1482
|
+
+ rbrace
|
|
1483
|
+
)
|
|
1484
|
+
.set_results_name("owa_integrals", list_all_matches=True)
|
|
1485
|
+
.set_parse_action(partial(_parse_owa_integral_concept, kb))
|
|
1486
|
+
)
|
|
1487
|
+
+ rbrace
|
|
1488
|
+
)
|
|
1489
|
+
|
|
1490
|
+
modifier = (
|
|
1491
|
+
(
|
|
1492
|
+
lbrace
|
|
1493
|
+
+ FuzzyDLKeyword.DEFINE_MODIFIER.get_value().suppress()
|
|
1494
|
+
+ variables
|
|
1495
|
+
+ (
|
|
1496
|
+
FuzzyDLKeyword.LINEAR_MODIFIER.get_value()
|
|
1497
|
+
+ lbrace
|
|
1498
|
+
+ numbers
|
|
1499
|
+
+ rbrace
|
|
1500
|
+
| FuzzyDLKeyword.TRIANGULAR_MODIFIER.get_value()
|
|
1501
|
+
+ lbrace
|
|
1502
|
+
+ numbers[3]
|
|
1503
|
+
+ rbrace
|
|
1504
|
+
)
|
|
1505
|
+
+ rbrace
|
|
1506
|
+
)
|
|
1507
|
+
.set_results_name("modifiers", list_all_matches=True)
|
|
1508
|
+
.set_parse_action(partial(_parse_modifier, kb))
|
|
1509
|
+
)
|
|
1510
|
+
|
|
1511
|
+
truth_constants = (
|
|
1512
|
+
(
|
|
1513
|
+
lbrace
|
|
1514
|
+
+ FuzzyDLKeyword.DEFINE_TRUTH_CONSTANT.get_value()
|
|
1515
|
+
+ variables
|
|
1516
|
+
+ numbers
|
|
1517
|
+
+ rbrace
|
|
1518
|
+
)
|
|
1519
|
+
.set_results_name("truth_concepts", list_all_matches=True)
|
|
1520
|
+
.set_parse_action(partial(_parse_truth_constants, kb))
|
|
1521
|
+
)
|
|
1522
|
+
|
|
1523
|
+
fuzzy_concept = (
|
|
1524
|
+
(
|
|
1525
|
+
lbrace
|
|
1526
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_CONCEPT.get_value().suppress()
|
|
1527
|
+
+ variables
|
|
1528
|
+
+ (
|
|
1529
|
+
FuzzyDLKeyword.CRISP.get_value()
|
|
1530
|
+
+ lbrace
|
|
1531
|
+
+ pp.DelimitedList(numbers, min=4, max=4)
|
|
1532
|
+
+ rbrace
|
|
1533
|
+
| FuzzyDLKeyword.LEFT_SHOULDER.get_value()
|
|
1534
|
+
+ lbrace
|
|
1535
|
+
+ pp.DelimitedList(numbers, min=4, max=4)
|
|
1536
|
+
+ rbrace
|
|
1537
|
+
| FuzzyDLKeyword.RIGHT_SHOULDER.get_value()
|
|
1538
|
+
+ lbrace
|
|
1539
|
+
+ pp.DelimitedList(numbers, min=4, max=4)
|
|
1540
|
+
+ rbrace
|
|
1541
|
+
| FuzzyDLKeyword.TRIANGULAR.get_value()
|
|
1542
|
+
+ lbrace
|
|
1543
|
+
+ pp.DelimitedList(numbers, min=5, max=5)
|
|
1544
|
+
+ rbrace
|
|
1545
|
+
| FuzzyDLKeyword.TRAPEZOIDAL.get_value()
|
|
1546
|
+
+ lbrace
|
|
1547
|
+
+ pp.DelimitedList(numbers, min=6, max=6)
|
|
1548
|
+
+ rbrace
|
|
1549
|
+
| FuzzyDLKeyword.LINEAR.get_value()
|
|
1550
|
+
+ lbrace
|
|
1551
|
+
+ pp.DelimitedList(numbers, min=4, max=4)
|
|
1552
|
+
+ rbrace
|
|
1553
|
+
| FuzzyDLKeyword.MODIFIED.get_value()
|
|
1554
|
+
+ lbrace
|
|
1555
|
+
+ pp.DelimitedList(variables, min=2, max=2)
|
|
1556
|
+
+ rbrace
|
|
1557
|
+
)
|
|
1558
|
+
+ rbrace
|
|
1559
|
+
)
|
|
1560
|
+
.set_results_name("fuzzy_concepts", list_all_matches=True)
|
|
1561
|
+
.set_parse_action(partial(_parse_fuzzy_concept, kb))
|
|
1562
|
+
)
|
|
1563
|
+
|
|
1564
|
+
fuzzy_range = (
|
|
1565
|
+
(
|
|
1566
|
+
lbrace
|
|
1567
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_NUMBER_RANGE.get_value().suppress()
|
|
1568
|
+
+ numbers[2]
|
|
1569
|
+
+ rbrace
|
|
1570
|
+
)
|
|
1571
|
+
.set_results_name("fuzzy_ranges", list_all_matches=True)
|
|
1572
|
+
.set_parse_action(partial(_parse_fuzzy_number_range, kb))
|
|
1573
|
+
)
|
|
1574
|
+
|
|
1575
|
+
features = (
|
|
1576
|
+
(
|
|
1577
|
+
lbrace
|
|
1578
|
+
+ (
|
|
1579
|
+
# Keyword.FUNCTIONAL.get_value() + variables |
|
|
1580
|
+
FuzzyDLKeyword.RANGE.get_value()
|
|
1581
|
+
+ variables
|
|
1582
|
+
+ (
|
|
1583
|
+
pp.one_of(
|
|
1584
|
+
[
|
|
1585
|
+
FuzzyDLKeyword.INTEGER.get_name(),
|
|
1586
|
+
FuzzyDLKeyword.REAL.get_name(),
|
|
1587
|
+
]
|
|
1588
|
+
)
|
|
1589
|
+
+ numbers[2]
|
|
1590
|
+
| pp.one_of(
|
|
1591
|
+
[
|
|
1592
|
+
FuzzyDLKeyword.STRING.get_name(),
|
|
1593
|
+
FuzzyDLKeyword.BOOLEAN.get_name(),
|
|
1594
|
+
]
|
|
1595
|
+
)
|
|
1596
|
+
)
|
|
1597
|
+
)
|
|
1598
|
+
+ rbrace
|
|
1599
|
+
)
|
|
1600
|
+
.set_results_name("features", list_all_matches=True)
|
|
1601
|
+
.set_parse_action(partial(_parse_feature, kb))
|
|
1602
|
+
)
|
|
1603
|
+
|
|
1604
|
+
expression = (
|
|
1605
|
+
pp.DelimitedList(
|
|
1606
|
+
numbers + FuzzyDLKeyword.MUL.get_value() + variables, delim="+"
|
|
1607
|
+
)
|
|
1608
|
+
.set_results_name("expressions", list_all_matches=True)
|
|
1609
|
+
.set_parse_action(partial(_parse_expression, kb))
|
|
1610
|
+
)
|
|
1611
|
+
|
|
1612
|
+
inequation = (
|
|
1613
|
+
(
|
|
1614
|
+
expression
|
|
1615
|
+
+ pp.one_of(
|
|
1616
|
+
[
|
|
1617
|
+
FuzzyDLKeyword.LESS_THAN_OR_EQUAL_TO.get_name(),
|
|
1618
|
+
FuzzyDLKeyword.GREATER_THAN_OR_EQUAL_TO.get_name(),
|
|
1619
|
+
FuzzyDLKeyword.EQUALS.get_name(),
|
|
1620
|
+
]
|
|
1621
|
+
)
|
|
1622
|
+
+ numbers
|
|
1623
|
+
)
|
|
1624
|
+
.set_results_name("inequations", list_all_matches=True)
|
|
1625
|
+
.set_parse_action(partial(_parse_inequation, kb))
|
|
1626
|
+
)
|
|
1627
|
+
|
|
1628
|
+
constraints = (
|
|
1629
|
+
(
|
|
1630
|
+
lbrace
|
|
1631
|
+
+ (
|
|
1632
|
+
inequation
|
|
1633
|
+
| FuzzyDLKeyword.BINARY.get_value() + variables
|
|
1634
|
+
| FuzzyDLKeyword.FREE.get_value() + variables
|
|
1635
|
+
)
|
|
1636
|
+
+ rbrace
|
|
1637
|
+
)
|
|
1638
|
+
.set_results_name("constraints", list_all_matches=True)
|
|
1639
|
+
.set_parse_action(partial(_parse_constraints, kb))
|
|
1640
|
+
)
|
|
1641
|
+
|
|
1642
|
+
show_concrete_fillers = (
|
|
1643
|
+
(
|
|
1644
|
+
lbrace
|
|
1645
|
+
+ FuzzyDLKeyword.SHOW_CONCRETE_FILLERS.get_value().suppress()
|
|
1646
|
+
+ pp.OneOrMore(variables)
|
|
1647
|
+
+ rbrace
|
|
1648
|
+
)
|
|
1649
|
+
.set_results_name("show_concrete_fillers", list_all_matches=True)
|
|
1650
|
+
.set_parse_action(partial(_show_concrete_fillers, kb))
|
|
1651
|
+
)
|
|
1652
|
+
|
|
1653
|
+
show_concrete_fillers_for = (
|
|
1654
|
+
(
|
|
1655
|
+
lbrace
|
|
1656
|
+
+ FuzzyDLKeyword.SHOW_CONCRETE_FILLERS_FOR.get_value().suppress()
|
|
1657
|
+
+ variables
|
|
1658
|
+
+ pp.OneOrMore(variables)
|
|
1659
|
+
+ rbrace
|
|
1660
|
+
)
|
|
1661
|
+
.set_results_name("show_concrete_fillers_for", list_all_matches=True)
|
|
1662
|
+
.set_parse_action(partial(_show_concrete_fillers_for, kb))
|
|
1663
|
+
)
|
|
1664
|
+
|
|
1665
|
+
show_concrete_instance_for = (
|
|
1666
|
+
(
|
|
1667
|
+
lbrace
|
|
1668
|
+
+ FuzzyDLKeyword.SHOW_CONCRETE_INSTANCE_FOR.get_value().suppress()
|
|
1669
|
+
+ variables
|
|
1670
|
+
+ variables
|
|
1671
|
+
+ pp.OneOrMore(variables)
|
|
1672
|
+
+ rbrace
|
|
1673
|
+
)
|
|
1674
|
+
.set_results_name("show_concrete_instance_for", list_all_matches=True)
|
|
1675
|
+
.set_parse_action(partial(_show_concrete_instance_for, kb))
|
|
1676
|
+
)
|
|
1677
|
+
|
|
1678
|
+
show_abstract_fillers = (
|
|
1679
|
+
(
|
|
1680
|
+
lbrace
|
|
1681
|
+
+ FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS.get_value().suppress()
|
|
1682
|
+
+ pp.OneOrMore(variables)
|
|
1683
|
+
+ rbrace
|
|
1684
|
+
)
|
|
1685
|
+
.set_results_name("show_abstract_fillers", list_all_matches=True)
|
|
1686
|
+
.set_parse_action(partial(_show_abstract_fillers, kb))
|
|
1687
|
+
)
|
|
1688
|
+
|
|
1689
|
+
show_abstract_fillers_for = (
|
|
1690
|
+
(
|
|
1691
|
+
lbrace
|
|
1692
|
+
+ FuzzyDLKeyword.SHOW_ABSTRACT_FILLERS_FOR.get_value().suppress()
|
|
1693
|
+
+ variables
|
|
1694
|
+
+ pp.OneOrMore(variables)
|
|
1695
|
+
+ rbrace
|
|
1696
|
+
)
|
|
1697
|
+
.set_results_name("show_abstract_fillers_for", list_all_matches=True)
|
|
1698
|
+
.set_parse_action(partial(_show_abstract_fillers_for, kb))
|
|
1699
|
+
)
|
|
1700
|
+
|
|
1701
|
+
show_concepts = (
|
|
1702
|
+
(
|
|
1703
|
+
lbrace
|
|
1704
|
+
+ FuzzyDLKeyword.SHOW_CONCEPTS.get_value().suppress()
|
|
1705
|
+
+ pp.OneOrMore(variables)
|
|
1706
|
+
+ rbrace
|
|
1707
|
+
)
|
|
1708
|
+
.set_results_name("show_concepts", list_all_matches=True)
|
|
1709
|
+
.set_parse_action(partial(_show_concepts, kb))
|
|
1710
|
+
)
|
|
1711
|
+
|
|
1712
|
+
show_instances = (
|
|
1713
|
+
(
|
|
1714
|
+
lbrace
|
|
1715
|
+
+ FuzzyDLKeyword.SHOW_INSTANCES.get_value().suppress()
|
|
1716
|
+
+ pp.OneOrMore(concept)
|
|
1717
|
+
+ rbrace
|
|
1718
|
+
)
|
|
1719
|
+
.set_results_name("show_instances", list_all_matches=True)
|
|
1720
|
+
.set_parse_action(partial(_show_instances, kb))
|
|
1721
|
+
)
|
|
1722
|
+
|
|
1723
|
+
show_variables = (
|
|
1724
|
+
(
|
|
1725
|
+
lbrace
|
|
1726
|
+
+ FuzzyDLKeyword.SHOW_VARIABLES.get_value().suppress()
|
|
1727
|
+
+ pp.OneOrMore(variables)
|
|
1728
|
+
+ rbrace
|
|
1729
|
+
)
|
|
1730
|
+
.set_results_name("show_variables", list_all_matches=True)
|
|
1731
|
+
.set_parse_action(partial(_show_variables, kb))
|
|
1732
|
+
)
|
|
1733
|
+
|
|
1734
|
+
show_languages = (
|
|
1735
|
+
(lbrace + FuzzyDLKeyword.SHOW_LANGUAGE.get_value().suppress() + rbrace)
|
|
1736
|
+
.set_results_name("show_languages", list_all_matches=True)
|
|
1737
|
+
.set_parse_action(partial(_show_languages, kb))
|
|
1738
|
+
)
|
|
1739
|
+
|
|
1740
|
+
show_statements = (
|
|
1741
|
+
show_concrete_fillers_for
|
|
1742
|
+
| show_concrete_fillers
|
|
1743
|
+
| show_concrete_instance_for
|
|
1744
|
+
| show_abstract_fillers_for
|
|
1745
|
+
| show_abstract_fillers
|
|
1746
|
+
| show_concepts
|
|
1747
|
+
| show_instances
|
|
1748
|
+
| show_variables
|
|
1749
|
+
| show_languages
|
|
1750
|
+
)
|
|
1751
|
+
|
|
1752
|
+
crisp_declarations = (
|
|
1753
|
+
(
|
|
1754
|
+
lbrace
|
|
1755
|
+
+ (
|
|
1756
|
+
FuzzyDLKeyword.CRISP_CONCEPT.get_value()
|
|
1757
|
+
| FuzzyDLKeyword.CRISP_ROLE.get_value()
|
|
1758
|
+
)
|
|
1759
|
+
+ pp.OneOrMore(variables)
|
|
1760
|
+
+ rbrace
|
|
1761
|
+
)
|
|
1762
|
+
.set_results_name("crisp_declarations", list_all_matches=True)
|
|
1763
|
+
.set_parse_action(partial(_parse_crisp_declarations, kb))
|
|
1764
|
+
)
|
|
1765
|
+
|
|
1766
|
+
fuzzy_similarity = (
|
|
1767
|
+
(
|
|
1768
|
+
lbrace
|
|
1769
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_SIMILARITY.get_value().suppress()
|
|
1770
|
+
+ variables
|
|
1771
|
+
+ rbrace
|
|
1772
|
+
)
|
|
1773
|
+
.set_results_name("fuzzy_similarities", list_all_matches=True)
|
|
1774
|
+
.set_parse_action(partial(_parse_fuzzy_similarity, kb))
|
|
1775
|
+
)
|
|
1776
|
+
|
|
1777
|
+
fuzzy_equivalence = (
|
|
1778
|
+
(
|
|
1779
|
+
lbrace
|
|
1780
|
+
+ FuzzyDLKeyword.DEFINE_FUZZY_EQUIVALENCE.get_value().suppress()
|
|
1781
|
+
+ variables
|
|
1782
|
+
+ rbrace
|
|
1783
|
+
)
|
|
1784
|
+
.set_results_name("fuzzy_equivalences", list_all_matches=True)
|
|
1785
|
+
.set_parse_action(partial(_parse_fuzzy_equivalence, kb))
|
|
1786
|
+
)
|
|
1787
|
+
|
|
1788
|
+
degree = (
|
|
1789
|
+
(numbers | expression | variables)
|
|
1790
|
+
.set_results_name("degrees", list_all_matches=True)
|
|
1791
|
+
.set_parse_action(partial(_parse_degree, kb))
|
|
1792
|
+
)
|
|
1793
|
+
|
|
1794
|
+
axioms = (
|
|
1795
|
+
(
|
|
1796
|
+
lbrace
|
|
1797
|
+
+ pp.Group(
|
|
1798
|
+
FuzzyDLKeyword.INSTANCE.get_value()
|
|
1799
|
+
+ variables
|
|
1800
|
+
+ concept
|
|
1801
|
+
+ pp.Opt(degree)
|
|
1802
|
+
| FuzzyDLKeyword.RELATED.get_value()
|
|
1803
|
+
+ variables
|
|
1804
|
+
+ variables
|
|
1805
|
+
+ variables
|
|
1806
|
+
+ pp.Opt(degree)
|
|
1807
|
+
| FuzzyDLKeyword.IMPLIES_ROLE.get_value()
|
|
1808
|
+
+ variables
|
|
1809
|
+
+ variables
|
|
1810
|
+
+ pp.Opt(numbers)
|
|
1811
|
+
| FuzzyDLKeyword.ZADEH_IMPLIES.get_value() + concept + concept
|
|
1812
|
+
| pp.one_of(
|
|
1813
|
+
[
|
|
1814
|
+
FuzzyDLKeyword.GOEDEL_IMPLIES.get_name(),
|
|
1815
|
+
FuzzyDLKeyword.LUKASIEWICZ_IMPLIES.get_name(),
|
|
1816
|
+
FuzzyDLKeyword.KLEENE_DIENES_IMPLIES.get_name(),
|
|
1817
|
+
FuzzyDLKeyword.IMPLIES.get_name(),
|
|
1818
|
+
]
|
|
1819
|
+
)
|
|
1820
|
+
+ concept
|
|
1821
|
+
+ concept
|
|
1822
|
+
+ pp.Opt(degree)
|
|
1823
|
+
| FuzzyDLKeyword.DEFINE_CONCEPT.get_value() + variables + concept
|
|
1824
|
+
| FuzzyDLKeyword.DEFINE_PRIMITIVE_CONCEPT.get_value()
|
|
1825
|
+
+ variables
|
|
1826
|
+
+ concept
|
|
1827
|
+
| FuzzyDLKeyword.EQUIVALENT_CONCEPTS.get_value() + concept + concept
|
|
1828
|
+
| FuzzyDLKeyword.DISJOINT_UNION.get_value() + pp.OneOrMore(concept)
|
|
1829
|
+
| FuzzyDLKeyword.DISJOINT.get_value() + pp.OneOrMore(concept)
|
|
1830
|
+
| FuzzyDLKeyword.RANGE.get_value() + variables + concept
|
|
1831
|
+
| FuzzyDLKeyword.DOMAIN.get_value() + variables + concept
|
|
1832
|
+
| pp.one_of(
|
|
1833
|
+
[
|
|
1834
|
+
FuzzyDLKeyword.INVERSE_FUNCTIONAL.get_name(),
|
|
1835
|
+
FuzzyDLKeyword.FUNCTIONAL.get_name(),
|
|
1836
|
+
FuzzyDLKeyword.REFLEXIVE.get_name(),
|
|
1837
|
+
FuzzyDLKeyword.SYMMETRIC.get_name(),
|
|
1838
|
+
FuzzyDLKeyword.TRANSITIVE.get_name(),
|
|
1839
|
+
]
|
|
1840
|
+
)
|
|
1841
|
+
+ variables
|
|
1842
|
+
| FuzzyDLKeyword.INVERSE.get_value() + variables + variables,
|
|
1843
|
+
)
|
|
1844
|
+
+ rbrace
|
|
1845
|
+
)
|
|
1846
|
+
.set_results_name("axioms", list_all_matches=True)
|
|
1847
|
+
.set_parse_action(partial(_parse_axioms, kb))
|
|
1848
|
+
)
|
|
1849
|
+
|
|
1850
|
+
queries = (
|
|
1851
|
+
(
|
|
1852
|
+
lbrace
|
|
1853
|
+
+ pp.Group(
|
|
1854
|
+
FuzzyDLKeyword.ALL_INSTANCES_QUERY.get_value() + concept
|
|
1855
|
+
| FuzzyDLKeyword.SAT_QUERY.get_value()
|
|
1856
|
+
| pp.one_of(
|
|
1857
|
+
[
|
|
1858
|
+
FuzzyDLKeyword.MAX_INSTANCE_QUERY.get_name(),
|
|
1859
|
+
FuzzyDLKeyword.MIN_INSTANCE_QUERY.get_name(),
|
|
1860
|
+
]
|
|
1861
|
+
)
|
|
1862
|
+
+ variables
|
|
1863
|
+
+ concept
|
|
1864
|
+
| pp.one_of(
|
|
1865
|
+
[
|
|
1866
|
+
FuzzyDLKeyword.MAX_SUBS_QUERY.get_name(),
|
|
1867
|
+
FuzzyDLKeyword.MIN_SUBS_QUERY.get_name(),
|
|
1868
|
+
FuzzyDLKeyword.MAX_G_SUBS_QUERY.get_name(),
|
|
1869
|
+
FuzzyDLKeyword.MIN_G_SUBS_QUERY.get_name(),
|
|
1870
|
+
FuzzyDLKeyword.MAX_L_SUBS_QUERY.get_name(),
|
|
1871
|
+
FuzzyDLKeyword.MIN_L_SUBS_QUERY.get_name(),
|
|
1872
|
+
FuzzyDLKeyword.MAX_KD_SUBS_QUERY.get_name(),
|
|
1873
|
+
FuzzyDLKeyword.MIN_KD_SUBS_QUERY.get_name(),
|
|
1874
|
+
]
|
|
1875
|
+
)
|
|
1876
|
+
+ concept
|
|
1877
|
+
+ concept
|
|
1878
|
+
| pp.one_of(
|
|
1879
|
+
[
|
|
1880
|
+
FuzzyDLKeyword.MAX_RELATED_QUERY.get_name(),
|
|
1881
|
+
FuzzyDLKeyword.MIN_RELATED_QUERY.get_name(),
|
|
1882
|
+
]
|
|
1883
|
+
)
|
|
1884
|
+
+ variables
|
|
1885
|
+
+ variables
|
|
1886
|
+
+ variables
|
|
1887
|
+
| pp.one_of(
|
|
1888
|
+
[
|
|
1889
|
+
FuzzyDLKeyword.MAX_SAT_QUERY.get_name(),
|
|
1890
|
+
FuzzyDLKeyword.MIN_SAT_QUERY.get_name(),
|
|
1891
|
+
]
|
|
1892
|
+
)
|
|
1893
|
+
+ concept
|
|
1894
|
+
+ pp.Opt(variables)
|
|
1895
|
+
| pp.one_of(
|
|
1896
|
+
[
|
|
1897
|
+
FuzzyDLKeyword.MAX_VAR_QUERY.get_name(),
|
|
1898
|
+
FuzzyDLKeyword.MIN_VAR_QUERY.get_name(),
|
|
1899
|
+
]
|
|
1900
|
+
)
|
|
1901
|
+
+ expression
|
|
1902
|
+
| pp.one_of(
|
|
1903
|
+
[
|
|
1904
|
+
FuzzyDLKeyword.DEFUZZIFY_LOM_QUERY.get_name(),
|
|
1905
|
+
FuzzyDLKeyword.DEFUZZIFY_SOM_QUERY.get_name(),
|
|
1906
|
+
FuzzyDLKeyword.DEFUZZIFY_MOM_QUERY.get_name(),
|
|
1907
|
+
]
|
|
1908
|
+
)
|
|
1909
|
+
+ concept
|
|
1910
|
+
+ variables
|
|
1911
|
+
+ variables
|
|
1912
|
+
| FuzzyDLKeyword.BNP_QUERY.get_value() + fuzzy_number_expr,
|
|
1913
|
+
)
|
|
1914
|
+
+ rbrace
|
|
1915
|
+
)
|
|
1916
|
+
.set_results_name("queries", list_all_matches=True)
|
|
1917
|
+
.set_parse_action(partial(_parse_queries, kb, queries_list))
|
|
1918
|
+
)
|
|
1919
|
+
|
|
1920
|
+
gformula = (
|
|
1921
|
+
comment_line
|
|
1922
|
+
| fuzzy_logic
|
|
1923
|
+
| axioms
|
|
1924
|
+
| truth_constants
|
|
1925
|
+
| modifier
|
|
1926
|
+
| fuzzy_concept
|
|
1927
|
+
| fuzzy_range
|
|
1928
|
+
| fuzzy_numbers
|
|
1929
|
+
| features
|
|
1930
|
+
| constraints
|
|
1931
|
+
| show_statements
|
|
1932
|
+
| crisp_declarations
|
|
1933
|
+
| concept
|
|
1934
|
+
| fuzzy_similarity
|
|
1935
|
+
| fuzzy_equivalence
|
|
1936
|
+
| queries
|
|
1937
|
+
)
|
|
1938
|
+
return pp.OneOrMore(gformula)
|
|
1939
|
+
|
|
1940
|
+
@staticmethod
|
|
1941
|
+
@utils.recursion_unlimited
|
|
1942
|
+
def parse_string(
|
|
1943
|
+
kb: KnowledgeBase,
|
|
1944
|
+
queries: list[Query],
|
|
1945
|
+
instring: str,
|
|
1946
|
+
) -> pp.ParseResults:
|
|
1947
|
+
return DLParser.get_grammatics(kb, queries).parse_string(
|
|
1948
|
+
instring, parse_all=True
|
|
1949
|
+
)
|
|
1950
|
+
|
|
1951
|
+
@staticmethod
|
|
1952
|
+
@utils.recursion_unlimited
|
|
1953
|
+
def parse_string_opt(
|
|
1954
|
+
kb: KnowledgeBase,
|
|
1955
|
+
queries: list[Query],
|
|
1956
|
+
filename: str,
|
|
1957
|
+
) -> pp.ParseResults:
|
|
1958
|
+
with open(filename, "r") as file:
|
|
1959
|
+
instring = file.read()
|
|
1960
|
+
|
|
1961
|
+
if ConfigReader.DEBUG_PRINT:
|
|
1962
|
+
return DLParser.get_grammatics(kb, queries).run_tests(
|
|
1963
|
+
instring,
|
|
1964
|
+
failure_tests=True,
|
|
1965
|
+
file=open(os.path.join(LOG_DIR, FILENAME), "w"),
|
|
1966
|
+
)
|
|
1967
|
+
else:
|
|
1968
|
+
return DLParser.get_grammatics(kb, queries).parse_string(instring)
|
|
1969
|
+
|
|
1970
|
+
@staticmethod
|
|
1971
|
+
def load_config(*args) -> None:
|
|
1972
|
+
ConfigReader.load_parameters(os.path.join(os.getcwd(), "CONFIG.ini"), args)
|
|
1973
|
+
|
|
1974
|
+
@staticmethod
|
|
1975
|
+
def get_kb(*args) -> tuple[KnowledgeBase, list[Query]]:
|
|
1976
|
+
try:
|
|
1977
|
+
starting_time: float = time.perf_counter_ns()
|
|
1978
|
+
DLParser.load_config(*args)
|
|
1979
|
+
kb: KnowledgeBase = KnowledgeBase()
|
|
1980
|
+
queries: list[Query] = []
|
|
1981
|
+
constants.KNOWLEDGE_BASE_SEMANTICS = FuzzyLogic.LUKASIEWICZ
|
|
1982
|
+
# with open(args[0], "r") as file:
|
|
1983
|
+
# lines = file.readlines()
|
|
1984
|
+
# for line in lines:
|
|
1985
|
+
# line = line.strip()
|
|
1986
|
+
# if line == "":
|
|
1987
|
+
# continue
|
|
1988
|
+
# if ConfigReader.DEBUG_PRINT:
|
|
1989
|
+
# Util.debug(f"Line -> {line}")
|
|
1990
|
+
# _ = DLParser.parse_string(kb, queries, line)
|
|
1991
|
+
_ = DLParser.parse_string_opt(kb, queries, args[0])
|
|
1992
|
+
ending_time: float = time.perf_counter_ns() - starting_time
|
|
1993
|
+
Util.info(f"Knowledge Base parsed in {(ending_time * 1e-9)}s")
|
|
1994
|
+
return kb, queries
|
|
1995
|
+
except FileNotFoundError as e:
|
|
1996
|
+
Util.error(f"Error: File {args[0]} not found.")
|
|
1997
|
+
except Exception as e:
|
|
1998
|
+
Util.error(e)
|
|
1999
|
+
Util.error(traceback.format_exc())
|
|
2000
|
+
|
|
2001
|
+
@staticmethod
|
|
2002
|
+
def main(*args) -> None:
|
|
2003
|
+
try:
|
|
2004
|
+
kb, queries = DLParser.get_kb(*args)
|
|
2005
|
+
kb.solve_kb()
|
|
2006
|
+
for query in queries:
|
|
2007
|
+
if (
|
|
2008
|
+
isinstance(query, AllInstancesQuery)
|
|
2009
|
+
and not kb.get_individuals().values()
|
|
2010
|
+
):
|
|
2011
|
+
Util.info(f"{query} -- There are no individuals in the fuzzy KB")
|
|
2012
|
+
else:
|
|
2013
|
+
result: Solution = query.solve(kb)
|
|
2014
|
+
if result.is_consistent_kb():
|
|
2015
|
+
Util.info(f"{query}{result}")
|
|
2016
|
+
else:
|
|
2017
|
+
Util.info("KnowledgeBase inconsistent: Answer is 1.0.")
|
|
2018
|
+
Util.info(f"Time (s): {query.get_total_time()}")
|
|
2019
|
+
if kb.show_language:
|
|
2020
|
+
Util.info(f"The language of the KB is {kb.get_language()}")
|
|
2021
|
+
except InconsistentOntologyException as e:
|
|
2022
|
+
Util.error("KnowledgeBase inconsistent: Any answer is 1.0.")
|
|
2023
|
+
except Exception as e:
|
|
2024
|
+
Util.error(e)
|
|
2025
|
+
Util.error(traceback.format_exc())
|
|
2026
|
+
|
|
2027
|
+
|
|
2028
|
+
if __name__ == "__main__":
|
|
2029
|
+
DLParser.main("./test.txt")
|