flamapy-sdd 2.6.0.dev11__tar.gz → 2.6.0.dev12__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.
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/PKG-INFO +3 -3
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/PKG-INFO +3 -3
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/requires.txt +2 -2
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/pyproject.toml +3 -3
- flamapy_sdd-2.6.0.dev12/tests/test_sdd.py +108 -0
- flamapy_sdd-2.6.0.dev11/tests/test_sdd.py +0 -82
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/LICENSE +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/README.md +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/__init__.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/models/__init__.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/models/sdd_model.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/operations/__init__.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/operations/sdd_configurations_number.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/operations/sdd_core_features.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/operations/sdd_dead_features.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/operations/sdd_satisfiable.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/transformations/__init__.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/transformations/fm_to_sdd.py +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/SOURCES.txt +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/dependency_links.txt +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/top_level.txt +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/setup.cfg +0 -0
- {flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flamapy-sdd
|
|
3
|
-
Version: 2.6.0.
|
|
3
|
+
Version: 2.6.0.dev12
|
|
4
4
|
Summary: flamapy-sdd is a plugin to flamapy providing Sentential Decision Diagram (SDD) knowledge compilation for exact analysis of feature models
|
|
5
5
|
Author-email: Flamapy <flamapy@us.es>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -8,8 +8,8 @@ Project-URL: Homepage, https://github.com/flamapy/sdd_metamodel
|
|
|
8
8
|
Requires-Python: >=3.11
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: flamapy-fw~=2.6.0.
|
|
12
|
-
Requires-Dist: flamapy-fm~=2.6.0.
|
|
11
|
+
Requires-Dist: flamapy-fw~=2.6.0.dev12
|
|
12
|
+
Requires-Dist: flamapy-fm~=2.6.0.dev12
|
|
13
13
|
Requires-Dist: PySDD~=1.0
|
|
14
14
|
Provides-Extra: dev
|
|
15
15
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flamapy-sdd
|
|
3
|
-
Version: 2.6.0.
|
|
3
|
+
Version: 2.6.0.dev12
|
|
4
4
|
Summary: flamapy-sdd is a plugin to flamapy providing Sentential Decision Diagram (SDD) knowledge compilation for exact analysis of feature models
|
|
5
5
|
Author-email: Flamapy <flamapy@us.es>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -8,8 +8,8 @@ Project-URL: Homepage, https://github.com/flamapy/sdd_metamodel
|
|
|
8
8
|
Requires-Python: >=3.11
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE
|
|
11
|
-
Requires-Dist: flamapy-fw~=2.6.0.
|
|
12
|
-
Requires-Dist: flamapy-fm~=2.6.0.
|
|
11
|
+
Requires-Dist: flamapy-fw~=2.6.0.dev12
|
|
12
|
+
Requires-Dist: flamapy-fm~=2.6.0.dev12
|
|
13
13
|
Requires-Dist: PySDD~=1.0
|
|
14
14
|
Provides-Extra: dev
|
|
15
15
|
Requires-Dist: pytest; extra == "dev"
|
|
@@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "flamapy-sdd"
|
|
7
|
-
version = "2.6.0.
|
|
7
|
+
version = "2.6.0.dev12"
|
|
8
8
|
description = "flamapy-sdd is a plugin to flamapy providing Sentential Decision Diagram (SDD) knowledge compilation for exact analysis of feature models"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "GPL-3.0-or-later"
|
|
11
11
|
authors = [{ name = "Flamapy", email = "flamapy@us.es" }]
|
|
12
12
|
requires-python = ">=3.11"
|
|
13
13
|
dependencies = [
|
|
14
|
-
"flamapy-fw~=2.6.0.
|
|
15
|
-
"flamapy-fm~=2.6.0.
|
|
14
|
+
"flamapy-fw~=2.6.0.dev12",
|
|
15
|
+
"flamapy-fm~=2.6.0.dev12",
|
|
16
16
|
"PySDD~=1.0",
|
|
17
17
|
]
|
|
18
18
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""Tests for the SDD metamodel: exact counting, satisfiability, core/dead features.
|
|
2
|
+
|
|
3
|
+
Oracles are computed by brute-forcing the CNF from fm_metamodel's solver-agnostic ClauseSet,
|
|
4
|
+
so CI needs no SAT plugin — only flamapy-fm, which is already a declared dependency.
|
|
5
|
+
"""
|
|
6
|
+
import os
|
|
7
|
+
import tempfile
|
|
8
|
+
from itertools import product
|
|
9
|
+
|
|
10
|
+
from flamapy.metamodels.fm_metamodel.transformations import UVLReader
|
|
11
|
+
from flamapy.metamodels.fm_metamodel.models import FeatureModel, ClauseSet
|
|
12
|
+
from flamapy.metamodels.sdd_metamodel.transformations import FmToSDD
|
|
13
|
+
from flamapy.metamodels.sdd_metamodel.operations import (
|
|
14
|
+
SDDConfigurationsNumber,
|
|
15
|
+
SDDSatisfiable,
|
|
16
|
+
SDDCoreFeatures,
|
|
17
|
+
SDDDeadFeatures,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _valid_configs(fm: FeatureModel) -> tuple:
|
|
22
|
+
"""(valid configurations as frozensets of selected names, all feature names)."""
|
|
23
|
+
clause_set = ClauseSet.from_feature_model(fm)
|
|
24
|
+
name_of = {vid: name for name, vid in clause_set.variables.items()}
|
|
25
|
+
var_ids = sorted({abs(lit) for clause in clause_set.clauses for lit in clause}
|
|
26
|
+
| set(clause_set.variables.values()))
|
|
27
|
+
configs = set()
|
|
28
|
+
for bits in product((False, True), repeat=len(var_ids)):
|
|
29
|
+
assignment = dict(zip(var_ids, bits))
|
|
30
|
+
if all(any((lit > 0) == assignment[abs(lit)] for lit in clause)
|
|
31
|
+
for clause in clause_set.clauses):
|
|
32
|
+
configs.add(frozenset(name_of[v] for v in var_ids if assignment[v] and v in name_of))
|
|
33
|
+
return configs, set(clause_set.variables)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _exact_count(fm: FeatureModel) -> int:
|
|
37
|
+
return len(_valid_configs(fm)[0])
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _core_features(fm: FeatureModel) -> set:
|
|
41
|
+
configs, names = _valid_configs(fm)
|
|
42
|
+
return {name for name in names if configs and all(name in cfg for cfg in configs)}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _dead_features(fm: FeatureModel) -> set:
|
|
46
|
+
configs, names = _valid_configs(fm)
|
|
47
|
+
return names - (set().union(*configs) if configs else set())
|
|
48
|
+
|
|
49
|
+
_UVL = """features
|
|
50
|
+
Root {abstract}
|
|
51
|
+
mandatory
|
|
52
|
+
Base
|
|
53
|
+
optional
|
|
54
|
+
A
|
|
55
|
+
B
|
|
56
|
+
C
|
|
57
|
+
constraints
|
|
58
|
+
A => B
|
|
59
|
+
A | B
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
_UNSAT_UVL = """features
|
|
63
|
+
Root {abstract}
|
|
64
|
+
mandatory
|
|
65
|
+
A
|
|
66
|
+
constraints
|
|
67
|
+
!A
|
|
68
|
+
"""
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _fm(uvl):
|
|
72
|
+
handle, path = tempfile.mkstemp(suffix='.uvl')
|
|
73
|
+
try:
|
|
74
|
+
with os.fdopen(handle, 'w') as file:
|
|
75
|
+
file.write(uvl)
|
|
76
|
+
return UVLReader(path).transform()
|
|
77
|
+
finally:
|
|
78
|
+
os.remove(path)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def test_count_matches_sat_enumeration():
|
|
82
|
+
fm = _fm(_UVL)
|
|
83
|
+
exact = _exact_count(fm)
|
|
84
|
+
sdd = SDDConfigurationsNumber().execute(FmToSDD(fm).transform()).get_result()
|
|
85
|
+
assert sdd == exact
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def test_satisfiable():
|
|
89
|
+
assert SDDSatisfiable().execute(FmToSDD(_fm(_UVL)).transform()).get_result() is True
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def test_unsatisfiable_model():
|
|
93
|
+
assert SDDSatisfiable().execute(FmToSDD(_fm(_UNSAT_UVL)).transform()).get_result() is False
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_core_features_match_sat():
|
|
97
|
+
fm = _fm(_UVL)
|
|
98
|
+
expected = _core_features(fm)
|
|
99
|
+
sdd = set(SDDCoreFeatures().execute(FmToSDD(fm).transform()).get_result())
|
|
100
|
+
assert sdd == expected
|
|
101
|
+
assert 'Base' in sdd and 'Root' in sdd # mandatory chain is core
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def test_dead_features_match_sat():
|
|
105
|
+
fm = _fm(_UVL)
|
|
106
|
+
expected = _dead_features(fm)
|
|
107
|
+
sdd = set(SDDDeadFeatures().execute(FmToSDD(fm).transform()).get_result())
|
|
108
|
+
assert sdd == expected # no dead features in this model
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"""Tests for the SDD metamodel: exact counting, satisfiability, core/dead features.
|
|
2
|
-
|
|
3
|
-
Oracles come from the SAT backend (a declared dependency) so CI needs no extra plugin.
|
|
4
|
-
"""
|
|
5
|
-
import os
|
|
6
|
-
import tempfile
|
|
7
|
-
|
|
8
|
-
from flamapy.metamodels.fm_metamodel.transformations import UVLReader
|
|
9
|
-
from flamapy.metamodels.sdd_metamodel.transformations import FmToSDD
|
|
10
|
-
from flamapy.metamodels.sdd_metamodel.operations import (
|
|
11
|
-
SDDConfigurationsNumber,
|
|
12
|
-
SDDSatisfiable,
|
|
13
|
-
SDDCoreFeatures,
|
|
14
|
-
SDDDeadFeatures,
|
|
15
|
-
)
|
|
16
|
-
from flamapy.metamodels.pysat_metamodel.transformations import FmToPysat
|
|
17
|
-
from flamapy.metamodels.pysat_metamodel.operations.pysat_configurations_number import (
|
|
18
|
-
PySATConfigurationsNumber,
|
|
19
|
-
)
|
|
20
|
-
from flamapy.metamodels.pysat_metamodel.operations.pysat_core_features import PySATCoreFeatures
|
|
21
|
-
from flamapy.metamodels.pysat_metamodel.operations.pysat_dead_features import PySATDeadFeatures
|
|
22
|
-
|
|
23
|
-
_UVL = """features
|
|
24
|
-
Root {abstract}
|
|
25
|
-
mandatory
|
|
26
|
-
Base
|
|
27
|
-
optional
|
|
28
|
-
A
|
|
29
|
-
B
|
|
30
|
-
C
|
|
31
|
-
constraints
|
|
32
|
-
A => B
|
|
33
|
-
A | B
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
_UNSAT_UVL = """features
|
|
37
|
-
Root {abstract}
|
|
38
|
-
mandatory
|
|
39
|
-
A
|
|
40
|
-
constraints
|
|
41
|
-
!A
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def _fm(uvl):
|
|
46
|
-
handle, path = tempfile.mkstemp(suffix='.uvl')
|
|
47
|
-
try:
|
|
48
|
-
with os.fdopen(handle, 'w') as file:
|
|
49
|
-
file.write(uvl)
|
|
50
|
-
return UVLReader(path).transform()
|
|
51
|
-
finally:
|
|
52
|
-
os.remove(path)
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def test_count_matches_sat_enumeration():
|
|
56
|
-
fm = _fm(_UVL)
|
|
57
|
-
exact = PySATConfigurationsNumber().execute(FmToPysat(fm).transform()).get_result()
|
|
58
|
-
sdd = SDDConfigurationsNumber().execute(FmToSDD(fm).transform()).get_result()
|
|
59
|
-
assert sdd == exact
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
def test_satisfiable():
|
|
63
|
-
assert SDDSatisfiable().execute(FmToSDD(_fm(_UVL)).transform()).get_result() is True
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
def test_unsatisfiable_model():
|
|
67
|
-
assert SDDSatisfiable().execute(FmToSDD(_fm(_UNSAT_UVL)).transform()).get_result() is False
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_core_features_match_sat():
|
|
71
|
-
fm = _fm(_UVL)
|
|
72
|
-
sat = set(PySATCoreFeatures().execute(FmToPysat(fm).transform()).get_result())
|
|
73
|
-
sdd = set(SDDCoreFeatures().execute(FmToSDD(fm).transform()).get_result())
|
|
74
|
-
assert sdd == sat
|
|
75
|
-
assert 'Base' in sdd and 'Root' in sdd # mandatory chain is core
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def test_dead_features_match_sat():
|
|
79
|
-
fm = _fm(_UVL)
|
|
80
|
-
sat = set(PySATDeadFeatures().execute(FmToPysat(fm).transform()).get_result())
|
|
81
|
-
sdd = set(SDDDeadFeatures().execute(FmToSDD(fm).transform()).get_result())
|
|
82
|
-
assert sdd == sat # no dead features in this model
|
|
File without changes
|
|
File without changes
|
{flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy/metamodels/sdd_metamodel/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{flamapy_sdd-2.6.0.dev11 → flamapy_sdd-2.6.0.dev12}/flamapy_sdd.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|