flamapy-dnnf 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.
Files changed (21) hide show
  1. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/PKG-INFO +3 -3
  2. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy_dnnf.egg-info/PKG-INFO +3 -3
  3. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy_dnnf.egg-info/requires.txt +2 -2
  4. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/pyproject.toml +3 -3
  5. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/tests/test_dnnf.py +20 -7
  6. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/LICENSE +0 -0
  7. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/README.md +0 -0
  8. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/__init__.py +0 -0
  9. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/models/__init__.py +0 -0
  10. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/models/dnnf_model.py +0 -0
  11. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/operations/__init__.py +0 -0
  12. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/operations/d4_runner.py +0 -0
  13. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/operations/dnnf_configurations_number.py +0 -0
  14. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/operations/dnnf_satisfiable.py +0 -0
  15. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/transformations/__init__.py +0 -0
  16. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy/metamodels/dnnf_metamodel/transformations/fm_to_dnnf.py +0 -0
  17. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy_dnnf.egg-info/SOURCES.txt +0 -0
  18. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy_dnnf.egg-info/dependency_links.txt +0 -0
  19. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/flamapy_dnnf.egg-info/top_level.txt +0 -0
  20. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/setup.cfg +0 -0
  21. {flamapy_dnnf-2.6.0.dev11 → flamapy_dnnf-2.6.0.dev12}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flamapy-dnnf
3
- Version: 2.6.0.dev11
3
+ Version: 2.6.0.dev12
4
4
  Summary: flamapy-dnnf is a plugin to flamapy providing exact analysis of feature models via d-DNNF knowledge compilation with the d4 compiler
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/dnnf_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.dev11
12
- Requires-Dist: flamapy-fm~=2.6.0.dev11
11
+ Requires-Dist: flamapy-fw~=2.6.0.dev12
12
+ Requires-Dist: flamapy-fm~=2.6.0.dev12
13
13
  Provides-Extra: dev
14
14
  Requires-Dist: pytest; extra == "dev"
15
15
  Requires-Dist: pytest-mock; extra == "dev"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flamapy-dnnf
3
- Version: 2.6.0.dev11
3
+ Version: 2.6.0.dev12
4
4
  Summary: flamapy-dnnf is a plugin to flamapy providing exact analysis of feature models via d-DNNF knowledge compilation with the d4 compiler
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/dnnf_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.dev11
12
- Requires-Dist: flamapy-fm~=2.6.0.dev11
11
+ Requires-Dist: flamapy-fw~=2.6.0.dev12
12
+ Requires-Dist: flamapy-fm~=2.6.0.dev12
13
13
  Provides-Extra: dev
14
14
  Requires-Dist: pytest; extra == "dev"
15
15
  Requires-Dist: pytest-mock; extra == "dev"
@@ -1,5 +1,5 @@
1
- flamapy-fw~=2.6.0.dev11
2
- flamapy-fm~=2.6.0.dev11
1
+ flamapy-fw~=2.6.0.dev12
2
+ flamapy-fm~=2.6.0.dev12
3
3
 
4
4
  [dev]
5
5
  pytest
@@ -4,15 +4,15 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "flamapy-dnnf"
7
- version = "2.6.0.dev11"
7
+ version = "2.6.0.dev12"
8
8
  description = "flamapy-dnnf is a plugin to flamapy providing exact analysis of feature models via d-DNNF knowledge compilation with the d4 compiler"
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.dev11",
15
- "flamapy-fm~=2.6.0.dev11",
14
+ "flamapy-fw~=2.6.0.dev12",
15
+ "flamapy-fm~=2.6.0.dev12",
16
16
  ]
17
17
 
18
18
  [project.optional-dependencies]
@@ -1,25 +1,38 @@
1
1
  """Tests for the d-DNNF (d4) metamodel.
2
2
 
3
3
  d4 is a native binary with no PyPI distribution, so these tests are skipped unless d4 is
4
- available (on PATH or via FLAMAPY_D4_PATH). When present, exact counts are checked against the
5
- SAT backend oracle.
4
+ available (on PATH or via FLAMAPY_D4_PATH). When present, exact counts are checked against an
5
+ oracle brute-forced from fm_metamodel's solver-agnostic ClauseSet (no SAT plugin needed).
6
6
  """
7
7
  import os
8
8
  import shutil
9
9
  import tempfile
10
+ from itertools import product
10
11
 
11
12
  import pytest
12
13
 
13
14
  from flamapy.metamodels.fm_metamodel.transformations import UVLReader
15
+ from flamapy.metamodels.fm_metamodel.models import FeatureModel, ClauseSet
14
16
  from flamapy.metamodels.dnnf_metamodel.transformations import FmToDDNNF
15
17
  from flamapy.metamodels.dnnf_metamodel.operations import (
16
18
  DDNNFConfigurationsNumber,
17
19
  DDNNFSatisfiable,
18
20
  )
19
- from flamapy.metamodels.pysat_metamodel.transformations import FmToPysat
20
- from flamapy.metamodels.pysat_metamodel.operations.pysat_configurations_number import (
21
- PySATConfigurationsNumber,
22
- )
21
+
22
+
23
+ def _exact_count(fm: FeatureModel) -> int:
24
+ """Exact configuration count by brute-forcing the ClauseSet CNF (no SAT backend)."""
25
+ clause_set = ClauseSet.from_feature_model(fm)
26
+ name_of = {vid: name for name, vid in clause_set.variables.items()}
27
+ var_ids = sorted({abs(lit) for clause in clause_set.clauses for lit in clause}
28
+ | set(clause_set.variables.values()))
29
+ configs = set()
30
+ for bits in product((False, True), repeat=len(var_ids)):
31
+ assignment = dict(zip(var_ids, bits))
32
+ if all(any((lit > 0) == assignment[abs(lit)] for lit in clause)
33
+ for clause in clause_set.clauses):
34
+ configs.add(frozenset(name_of[v] for v in var_ids if assignment[v] and v in name_of))
35
+ return len(configs)
23
36
 
24
37
  _D4_AVAILABLE = bool(os.environ.get('FLAMAPY_D4_PATH') or shutil.which('d4'))
25
38
  requires_d4 = pytest.mark.skipif(not _D4_AVAILABLE, reason='the d4 compiler is not installed')
@@ -51,7 +64,7 @@ def _fm(uvl):
51
64
  @requires_d4
52
65
  def test_count_matches_sat():
53
66
  fm = _fm(_UVL)
54
- exact = PySATConfigurationsNumber().execute(FmToPysat(fm).transform()).get_result()
67
+ exact = _exact_count(fm)
55
68
  dnnf = DDNNFConfigurationsNumber().execute(FmToDDNNF(fm).transform()).get_result()
56
69
  assert dnnf == exact
57
70