flamapy-fm 2.6.0.dev5__tar.gz → 2.6.0.dev7__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 (63) hide show
  1. {flamapy_fm-2.6.0.dev5/flamapy_fm.egg-info → flamapy_fm-2.6.0.dev7}/PKG-INFO +1 -1
  2. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/__init__.py +2 -0
  3. flamapy_fm-2.6.0.dev7/flamapy/metamodels/fm_metamodel/operations/fm_generate_random_feature_model.py +100 -0
  4. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7/flamapy_fm.egg-info}/PKG-INFO +1 -1
  5. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy_fm.egg-info/SOURCES.txt +1 -0
  6. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/pyproject.toml +1 -1
  7. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/LICENSE +0 -0
  8. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/README.md +0 -0
  9. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/__init__.py +0 -0
  10. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/models/__init__.py +0 -0
  11. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/models/feature_model.py +0 -0
  12. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_atomic_sets.py +0 -0
  13. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_average_branching_factor.py +0 -0
  14. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_core_features.py +0 -0
  15. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_count_leafs.py +0 -0
  16. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_estimated_configurations_number.py +0 -0
  17. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_feature_ancestors.py +0 -0
  18. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_generate_random_attribute.py +0 -0
  19. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_language_level.py +0 -0
  20. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_leaf_features.py +0 -0
  21. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_max_depth_tree.py +0 -0
  22. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_metrics.py +0 -0
  23. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/fm_variation_points.py +0 -0
  24. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/interfaces/__init__.py +0 -0
  25. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/operations/interfaces/variation_points.py +0 -0
  26. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/__init__.py +0 -0
  27. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/afm_reader.py +0 -0
  28. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/afm_writer.py +0 -0
  29. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/clafer_writer.py +0 -0
  30. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/featureide_reader.py +0 -0
  31. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/featureide_writer.py +0 -0
  32. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/flat_fm.py +0 -0
  33. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/fm_secure_features_names.py +0 -0
  34. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/glencoe_reader.py +0 -0
  35. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/glencoe_writer.py +0 -0
  36. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/json_reader.py +0 -0
  37. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/json_writer.py +0 -0
  38. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/pl_writer.py +0 -0
  39. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/pysat_to_fm.py +0 -0
  40. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/__init__.py +0 -0
  41. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/cardinality_group_refactoring.py +0 -0
  42. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/commitment_feature.py +0 -0
  43. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/deletion_feature.py +0 -0
  44. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/feature_cardinality_refactoring.py +0 -0
  45. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/feature_cardinality_refactoring_paper.py +0 -0
  46. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/multiple_group_decomposition_refactoring.py +0 -0
  47. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/mutex_group_refactoring.py +0 -0
  48. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/or_mandatory_refactoring.py +0 -0
  49. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/pseudocomplex_constraint_refactoring.py +0 -0
  50. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/refactoring_exception.py +0 -0
  51. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/refactoring_interface.py +0 -0
  52. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/strictcomplex_constraint_refactoring.py +0 -0
  53. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/refactorings/xor_mandatory_refactoring.py +0 -0
  54. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/splot_writer.py +0 -0
  55. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/uvl_reader.py +0 -0
  56. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/uvl_writer.py +0 -0
  57. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/xml_reader.py +0 -0
  58. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy/metamodels/fm_metamodel/transformations/xml_writer.py +0 -0
  59. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy_fm.egg-info/dependency_links.txt +0 -0
  60. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy_fm.egg-info/requires.txt +0 -0
  61. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/flamapy_fm.egg-info/top_level.txt +0 -0
  62. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/setup.cfg +0 -0
  63. {flamapy_fm-2.6.0.dev5 → flamapy_fm-2.6.0.dev7}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flamapy-fm
3
- Version: 2.6.0.dev5
3
+ Version: 2.6.0.dev7
4
4
  Summary: flamapy-fm is a plugin to Flamapy module
5
5
  Author-email: Flamapy <flamapy@us.es>
6
6
  License-Expression: GPL-3.0-or-later
@@ -8,6 +8,7 @@ from .fm_estimated_configurations_number import FMEstimatedConfigurationsNumber
8
8
  from .fm_atomic_sets import FMAtomicSets
9
9
  from .fm_metrics import FMMetrics
10
10
  from .fm_generate_random_attribute import GenerateRandomAttribute
11
+ from .fm_generate_random_feature_model import GenerateRandomFeatureModel
11
12
  from .fm_variation_points import FMVariationPoints
12
13
  from .fm_language_level import FMLanguageLevel, LanguageLevel, MajorLevel, MinorLevel
13
14
 
@@ -25,6 +26,7 @@ __all__ = [
25
26
  'FMMetrics',
26
27
  'FMVariationPoints',
27
28
  'GenerateRandomAttribute',
29
+ 'GenerateRandomFeatureModel',
28
30
  'LanguageLevel',
29
31
  'MajorLevel',
30
32
  'MinorLevel'
@@ -0,0 +1,100 @@
1
+ import os
2
+ import random
3
+ import tempfile
4
+ from typing import Optional
5
+
6
+ from flamapy.core.models import VariabilityModel
7
+ from flamapy.core.operations import Operation
8
+ from flamapy.metamodels.fm_metamodel.models import FeatureModel
9
+ from flamapy.metamodels.fm_metamodel.transformations import UVLReader
10
+
11
+ # Minimum children an or/alternative group needs (and minimum features for a cross-tree constraint).
12
+ _MIN_GROUP_MEMBERS = 2
13
+
14
+
15
+ class GenerateRandomFeatureModel(Operation):
16
+ """Generate a random synthetic feature model.
17
+
18
+ A random feature tree (mandatory/optional/or/alternative groups) plus random cross-tree
19
+ constraints are emitted as UVL and parsed back into a :class:`FeatureModel`. Useful to build
20
+ corpora for benchmarking, testing, or training learning-based operations. When ``void`` is
21
+ set, a contradictory constraint is added so the resulting model is unsatisfiable.
22
+
23
+ The operation produces a model, so ``execute`` ignores its (optional) input model.
24
+ """
25
+
26
+ def __init__(self) -> None:
27
+ self.result: FeatureModel
28
+ self._num_features: int = 10
29
+ self._max_constraints: int = 3
30
+ self._seed: int = 0
31
+ self._void: bool = False
32
+
33
+ def get_result(self) -> FeatureModel:
34
+ return self.result
35
+
36
+ def set_num_features(self, num_features: int) -> None:
37
+ self._num_features = max(2, num_features)
38
+
39
+ def set_max_constraints(self, max_constraints: int) -> None:
40
+ self._max_constraints = max(0, max_constraints)
41
+
42
+ def set_seed(self, seed: int) -> None:
43
+ self._seed = seed
44
+
45
+ def set_void(self, void: bool) -> None:
46
+ self._void = void
47
+
48
+ def _emit_uvl(self, rng: random.Random) -> str:
49
+ names = [f'F{i}' for i in range(self._num_features)]
50
+ root = names[0]
51
+ lines = ['features', f' {root} {{abstract}}']
52
+
53
+ children: dict[str, list[str]] = {name: [] for name in names}
54
+ for name in names[1:]:
55
+ parent = rng.choice(names[: names.index(name)])
56
+ children[parent].append(name)
57
+
58
+ def emit(parent: str, depth: int) -> None:
59
+ kids = children[parent]
60
+ if not kids:
61
+ return
62
+ indent = ' ' * (depth + 1)
63
+ group = rng.choice(['mandatory', 'optional', 'or', 'alternative'])
64
+ if group in ('or', 'alternative') and len(kids) < _MIN_GROUP_MEMBERS:
65
+ group = 'optional'
66
+ lines.append(f'{indent}{group}')
67
+ lines.extend(f'{indent} {kid}' for kid in kids)
68
+ for kid in kids:
69
+ emit(kid, depth + 2)
70
+
71
+ emit(root, 1)
72
+
73
+ constraints = []
74
+ non_root = names[1:]
75
+ if len(non_root) >= _MIN_GROUP_MEMBERS and self._max_constraints > 0:
76
+ for _ in range(rng.randint(1, self._max_constraints)):
77
+ left, right = rng.sample(non_root, 2)
78
+ constraints.append(
79
+ rng.choice([f'{left} => {right}', f'!{left} | {right}', f'!{left} | !{right}'])
80
+ )
81
+ if self._void and non_root:
82
+ forced = rng.choice(non_root)
83
+ constraints.append(f'{root} => {forced}')
84
+ constraints.append(f'!{forced}')
85
+ if constraints:
86
+ lines.append('constraints')
87
+ lines.extend(f' {constraint}' for constraint in constraints)
88
+ return '\n'.join(lines) + '\n'
89
+
90
+ def execute(self, model: Optional[VariabilityModel] = None) -> 'GenerateRandomFeatureModel':
91
+ rng = random.Random(self._seed)
92
+ uvl = self._emit_uvl(rng)
93
+ handle, path = tempfile.mkstemp(suffix='.uvl')
94
+ try:
95
+ with os.fdopen(handle, 'w') as file:
96
+ file.write(uvl)
97
+ self.result = UVLReader(path).transform()
98
+ finally:
99
+ os.remove(path)
100
+ return self
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flamapy-fm
3
- Version: 2.6.0.dev5
3
+ Version: 2.6.0.dev7
4
4
  Summary: flamapy-fm is a plugin to Flamapy module
5
5
  Author-email: Flamapy <flamapy@us.es>
6
6
  License-Expression: GPL-3.0-or-later
@@ -13,6 +13,7 @@ flamapy/metamodels/fm_metamodel/operations/fm_count_leafs.py
13
13
  flamapy/metamodels/fm_metamodel/operations/fm_estimated_configurations_number.py
14
14
  flamapy/metamodels/fm_metamodel/operations/fm_feature_ancestors.py
15
15
  flamapy/metamodels/fm_metamodel/operations/fm_generate_random_attribute.py
16
+ flamapy/metamodels/fm_metamodel/operations/fm_generate_random_feature_model.py
16
17
  flamapy/metamodels/fm_metamodel/operations/fm_language_level.py
17
18
  flamapy/metamodels/fm_metamodel/operations/fm_leaf_features.py
18
19
  flamapy/metamodels/fm_metamodel/operations/fm_max_depth_tree.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flamapy-fm"
7
- version = "2.6.0.dev5"
7
+ version = "2.6.0.dev7"
8
8
  description = "flamapy-fm is a plugin to Flamapy module"
9
9
  readme = "README.md"
10
10
  license = "GPL-3.0-or-later"
File without changes