flamapy-fw 2.0.0.dev7__tar.gz → 2.0.2.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/PKG-INFO +1 -1
  2. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/discover.py +14 -4
  3. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/models/ast.py +81 -2
  4. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/metrics_operation.py +3 -3
  5. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/satisfiable_configuration.py +1 -1
  6. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/metamodels/configuration_metamodel/models/configuration.py +4 -0
  7. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/PKG-INFO +1 -1
  8. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/setup.py +1 -1
  9. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/README.md +0 -0
  10. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/__init__.py +0 -0
  11. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/config.py +0 -0
  12. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/exceptions.py +0 -0
  13. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/models/__init__.py +0 -0
  14. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/models/variability_model.py +0 -0
  15. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/__init__.py +0 -0
  16. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/abstract_operation.py +0 -0
  17. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/atomic_sets.py +0 -0
  18. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/average_branching_factor.py +0 -0
  19. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/commonality.py +0 -0
  20. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/configurations.py +0 -0
  21. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/configurations_number.py +0 -0
  22. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/core_features.py +0 -0
  23. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/count_leafs.py +0 -0
  24. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/dead_features.py +0 -0
  25. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/error_detection.py +0 -0
  26. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/error_diagnosis.py +0 -0
  27. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/estimated_configurations_number.py +0 -0
  28. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/false_optional_features.py +0 -0
  29. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/filter.py +0 -0
  30. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/sampling.py +0 -0
  31. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/satisfiable.py +0 -0
  32. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/operations/variability.py +0 -0
  33. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/plugins.py +0 -0
  34. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/transformations/__init__.py +0 -0
  35. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/transformations/abstract_transformation.py +0 -0
  36. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/transformations/model_to_model.py +0 -0
  37. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/transformations/model_to_text.py +0 -0
  38. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/transformations/text_to_model.py +0 -0
  39. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/core/utils.py +0 -0
  40. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/metamodels/configuration_metamodel/__init__.py +0 -0
  41. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/metamodels/configuration_metamodel/models/__init__.py +0 -0
  42. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/metamodels/configuration_metamodel/transformations/__init__.py +0 -0
  43. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy/metamodels/configuration_metamodel/transformations/configuration_basic_reader.py +0 -0
  44. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/SOURCES.txt +0 -0
  45. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/dependency_links.txt +0 -0
  46. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/entry_points.txt +0 -0
  47. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/requires.txt +0 -0
  48. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/flamapy_fw.egg-info/top_level.txt +0 -0
  49. {flamapy-fw-2.0.0.dev7 → flamapy-fw-2.0.2.dev0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flamapy-fw
3
- Version: 2.0.0.dev7
3
+ Version: 2.0.2.dev0
4
4
  Summary: Flamapy is a Python-based AAFM framework that takes into consideration previous AAFM tool designs and enables multi-solver and multi-metamodel support for the integration of AAFM tooling on the Python ecosystem.
5
5
  Home-page: https://github.com/flamapy/core
6
6
  Author: Flamapy
@@ -179,12 +179,14 @@ class DiscoverMetamodels:
179
179
  operation = plugin.get_operation(operation_name)
180
180
  return plugin.use_operation(operation, src)
181
181
 
182
+ # pylint: disable=too-many-arguments
182
183
  def use_operation_from_vm(
183
184
  self,
184
185
  operation_name: str,
185
186
  vm_orig: VariabilityModel,
186
187
  plugin_name: Optional[str] = None,
187
- configuration_file: Optional[str] = None
188
+ configuration_file: Optional[str] = None,
189
+ is_full: Optional[bool] = False
188
190
  ) -> Any:
189
191
 
190
192
  if operation_name not in self.get_name_operations():
@@ -212,18 +214,23 @@ class DiscoverMetamodels:
212
214
  if configuration_file is None:
213
215
  raise ConfigurationNotFound()
214
216
  configuration = self.__transform_to_model_from_file(configuration_file)
215
- operation.set_configuration(cast(Configuration, configuration))
217
+ configuration = cast(Configuration, configuration)
218
+ is_full_value = is_full if is_full is not None else False
219
+ configuration.set_full(is_full_value)
220
+ operation.set_configuration(configuration)
216
221
 
217
222
  operation = plugin.use_operation(operation, vm_temp)
218
223
 
219
224
  return operation.get_result()
220
225
 
226
+ # pylint: disable=too-many-arguments
221
227
  def use_operation_from_file(
222
228
  self,
223
229
  operation_name: str,
224
230
  file: str,
225
231
  plugin_name: Optional[str] = None,
226
- configuration_file: Optional[str] = None
232
+ configuration_file: Optional[str] = None,
233
+ is_full: Optional[bool] = False
227
234
  ) -> Any:
228
235
 
229
236
  if operation_name not in self.get_name_operations():
@@ -251,7 +258,10 @@ class DiscoverMetamodels:
251
258
  if configuration_file is None:
252
259
  raise ConfigurationNotFound()
253
260
  configuration = self.__transform_to_model_from_file(configuration_file)
254
- operation.set_configuration(cast(Configuration, configuration))
261
+ configuration = cast(Configuration, configuration)
262
+ is_full_value = is_full if is_full is not None else False
263
+ configuration.set_full(is_full_value)
264
+ operation.set_configuration(configuration)
255
265
 
256
266
  operation = plugin.use_operation(operation, vm_temp)
257
267
  return operation.get_result()
@@ -1,8 +1,10 @@
1
+ import string
1
2
  from typing import Any
2
3
  from enum import Enum
3
4
 
4
5
 
5
6
  class ASTOperation(Enum):
7
+ # logical operators
6
8
  REQUIRES = 'REQUIRES'
7
9
  EXCLUDES = 'EXCLUDES'
8
10
  AND = 'AND'
@@ -33,6 +35,35 @@ class ASTOperation(Enum):
33
35
  CEIL = 'CEIL'
34
36
 
35
37
 
38
+ LOGICAL_OPERATORS = [ASTOperation.REQUIRES,
39
+ ASTOperation.EXCLUDES,
40
+ ASTOperation.AND,
41
+ ASTOperation.OR,
42
+ ASTOperation.XOR,
43
+ ASTOperation.IMPLIES,
44
+ ASTOperation.NOT,
45
+ ASTOperation.EQUIVALENCE]
46
+
47
+
48
+ ARITHMETIC_OPERATORS = [ASTOperation.ADD,
49
+ ASTOperation.SUB,
50
+ ASTOperation.MUL,
51
+ ASTOperation.DIV,
52
+ ASTOperation.EQUALS,
53
+ ASTOperation.LOWER,
54
+ ASTOperation.GREATER,
55
+ ASTOperation.LOWER_EQUALS,
56
+ ASTOperation.GREATER_EQUALS,
57
+ ASTOperation.NOT_EQUALS]
58
+
59
+
60
+ AGGREGATION_OPERATORS = [ASTOperation.SUM,
61
+ ASTOperation.AVG,
62
+ ASTOperation.LEN,
63
+ ASTOperation.FLOOR,
64
+ ASTOperation.CEIL]
65
+
66
+
36
67
  class Node:
37
68
 
38
69
  def __init__(self, data: Any, left: 'Node' = None, right: 'Node' = None): # type: ignore
@@ -53,7 +84,10 @@ class Node:
53
84
  return not self.is_op() and self.left is None
54
85
 
55
86
  def is_binary_op(self) -> bool:
56
- return not self.is_unique_term() and not self.is_unary_op()
87
+ return not self.is_unique_term() and not self.is_unary_op() and not self.is_aggregate_op()
88
+
89
+ def is_aggregate_op(self) -> bool:
90
+ return self.is_op() and self.data in AGGREGATION_OPERATORS
57
91
 
58
92
  def __str__(self) -> str:
59
93
  data = self.data.value if self.is_op() else safename(str(self.data))
@@ -85,6 +119,9 @@ class Node:
85
119
  res = f'{data}'
86
120
  elif self.is_unary_op():
87
121
  res = f'{data} {left}'
122
+ elif self.is_aggregate_op():
123
+ if self.right is not None:
124
+ res = f'{data}({left}, {right})'
88
125
  else: # binary operation
89
126
  res = f'{left} {data} {right}'
90
127
  return res
@@ -120,6 +157,36 @@ class AST:
120
157
  ast = self.to_cnf()
121
158
  return get_clauses(ast)
122
159
 
160
+ def get_operators(self) -> list[ASTOperation]:
161
+ operators = list()
162
+ stack = [self.root]
163
+ while stack:
164
+ node = stack.pop()
165
+ if node is not None:
166
+ if node.is_op():
167
+ operators.append(node.data)
168
+ if node.is_unary_op():
169
+ stack.append(node.left)
170
+ elif node.is_binary_op():
171
+ stack.append(node.right)
172
+ stack.append(node.left)
173
+ return operators
174
+
175
+ def get_operands(self) -> list[Any]:
176
+ operands = list()
177
+ stack = [self.root]
178
+ while stack:
179
+ node = stack.pop()
180
+ if node is not None:
181
+ if node.is_term():
182
+ operands.append(node.data)
183
+ elif node.is_unary_op():
184
+ stack.append(node.left)
185
+ elif node.is_binary_op():
186
+ stack.append(node.right)
187
+ stack.append(node.left)
188
+ return operands
189
+
123
190
  def __str__(self) -> str:
124
191
  return str(self.root)
125
192
 
@@ -305,4 +372,16 @@ def get_clause_from_or_node(node: Node) -> list[Any]:
305
372
 
306
373
 
307
374
  def safename(name: str) -> str:
308
- return f'"{name}"' if ' ' in name else name
375
+ if '.' in name:
376
+ return '.'.join([safe_simple_name(simple_name) for simple_name in name.split('.')])
377
+ return safe_simple_name(name)
378
+
379
+
380
+ def safe_simple_name(name: str) -> str:
381
+ if name.startswith("'") and name.endswith("'"):
382
+ return name
383
+ return f'"{name}"' if any(char not in safecharacters() for char in name) else name
384
+
385
+
386
+ def safecharacters() -> str:
387
+ return string.ascii_letters + string.digits + '_'
@@ -69,7 +69,7 @@ class Metrics(Operation, metaclass=ABCMeta):
69
69
  return m_to_m
70
70
  except FlamaException:
71
71
  LOGGER.exception("No transformation found that is required in the Metrics operation")
72
- raise FlamaException("No transformation found")
72
+ raise FlamaException(f"No transformation found for {orig} -> {dest}")
73
73
 
74
74
  def get_result(self) -> list[dict[str, Any]]:
75
75
  return self.result
@@ -92,8 +92,8 @@ class Metrics(Operation, metaclass=ABCMeta):
92
92
  def construct_result(name: str,
93
93
  doc: str,
94
94
  result: Any,
95
- size: int = 0,
96
- ratio: float = 0.0,
95
+ size: Optional[int] = None,
96
+ ratio: Optional[float] = None,
97
97
  parent: Optional[Any] = None,
98
98
  level: int = 0
99
99
  ) -> dict[str, Any]:
@@ -11,7 +11,7 @@ class SatisfiableConfiguration(Operation):
11
11
  pass
12
12
 
13
13
  @abstractmethod
14
- def set_configuration(self, configuration: Configuration, is_full: bool) -> None:
14
+ def set_configuration(self, configuration: Configuration) -> None:
15
15
  pass
16
16
 
17
17
  @abstractmethod
@@ -10,6 +10,10 @@ class Configuration(VariabilityModel):
10
10
 
11
11
  def __init__(self, elements: dict[Any, bool]) -> None:
12
12
  self.elements = elements
13
+ self.is_full = False
14
+
15
+ def set_full(self, is_full: bool) -> None:
16
+ self.is_full = is_full
13
17
 
14
18
  def get_selected_elements(self) -> list[Any]:
15
19
  return [e for e in self.elements if self.elements[e]]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: flamapy-fw
3
- Version: 2.0.0.dev7
3
+ Version: 2.0.2.dev0
4
4
  Summary: Flamapy is a Python-based AAFM framework that takes into consideration previous AAFM tool designs and enables multi-solver and multi-metamodel support for the integration of AAFM tooling on the Python ecosystem.
5
5
  Home-page: https://github.com/flamapy/core
6
6
  Author: Flamapy
@@ -13,7 +13,7 @@ dev_requirements = read_requirements("requirements-dev.txt")
13
13
 
14
14
  setuptools.setup(
15
15
  name="flamapy-fw",
16
- version="2.0.0.dev7",
16
+ version="2.0.2.dev0",
17
17
  author="Flamapy",
18
18
  author_email="flamapy@us.es",
19
19
  description="Flamapy is a Python-based AAFM framework that takes into consideration previous AAFM tool designs and enables multi-solver and multi-metamodel support for the integration of AAFM tooling on the Python ecosystem.",