ASP-based solver: permit to use virtual specs in environments (#24199)
Extracting specs for the result of a solve has been factored as a method into the asp.Result class. The method account for virtual specs being passed as initial requests.
This commit is contained in:
parent
e321578bbe
commit
f33c4e7280
4 changed files with 50 additions and 17 deletions
|
@ -116,9 +116,7 @@ def solve(parser, args):
|
|||
|
||||
# dump the solutions as concretized specs
|
||||
if 'solutions' in dump:
|
||||
best = min(result.answers)
|
||||
|
||||
opt, _, answer = best
|
||||
opt, _, _ = min(result.answers)
|
||||
if ("opt" in dump) and (not args.format):
|
||||
tty.msg("Best of %d considered solutions." % result.nmodels)
|
||||
tty.msg("Optimization Criteria:")
|
||||
|
@ -132,16 +130,7 @@ def solve(parser, args):
|
|||
color.cprint(fmt % (i + 1, name, val))
|
||||
print()
|
||||
|
||||
# iterate over roots from command line
|
||||
for input_spec in specs:
|
||||
key = input_spec.name
|
||||
if input_spec.virtual:
|
||||
providers = [spec.name for spec in answer.values()
|
||||
if spec.package.provides(key)]
|
||||
key = providers[0]
|
||||
|
||||
spec = answer[key]
|
||||
|
||||
for spec in result.specs:
|
||||
# With -y, just print YAML to output.
|
||||
if args.format == 'yaml':
|
||||
# use write because to_yaml already has a newline.
|
||||
|
|
|
@ -737,8 +737,7 @@ def _concretize_specs_together_new(*abstract_specs, **kwargs):
|
|||
result.print_cores()
|
||||
tty.die("Unsatisfiable spec.")
|
||||
|
||||
opt, i, answer = min(result.answers)
|
||||
return [answer[s.name].copy() for s in abstract_specs]
|
||||
return [s.copy() for s in result.specs]
|
||||
|
||||
|
||||
def _concretize_specs_together_original(*abstract_specs, **kwargs):
|
||||
|
|
|
@ -197,7 +197,7 @@ def check_packages_exist(specs):
|
|||
|
||||
class Result(object):
|
||||
"""Result of an ASP solve."""
|
||||
def __init__(self, asp=None):
|
||||
def __init__(self, specs, asp=None):
|
||||
self.asp = asp
|
||||
self.satisfiable = None
|
||||
self.optimal = None
|
||||
|
@ -211,12 +211,45 @@ def __init__(self, asp=None):
|
|||
# names of optimization criteria
|
||||
self.criteria = []
|
||||
|
||||
# Abstract user requests
|
||||
self.abstract_specs = specs
|
||||
|
||||
# Concrete specs
|
||||
self._concrete_specs = None
|
||||
|
||||
def print_cores(self):
|
||||
for core in self.cores:
|
||||
tty.msg(
|
||||
"The following constraints are unsatisfiable:",
|
||||
*sorted(str(symbol) for symbol in core))
|
||||
|
||||
@property
|
||||
def specs(self):
|
||||
"""List of concretized specs satisfying the initial
|
||||
abstract request.
|
||||
"""
|
||||
# The specs were already computed, return them
|
||||
if self._concrete_specs:
|
||||
return self._concrete_specs
|
||||
|
||||
# Assert prerequisite
|
||||
msg = 'cannot compute specs ["satisfiable" is not True ]'
|
||||
assert self.satisfiable, msg
|
||||
|
||||
self._concrete_specs = []
|
||||
best = min(self.answers)
|
||||
opt, _, answer = best
|
||||
for input_spec in self.abstract_specs:
|
||||
key = input_spec.name
|
||||
if input_spec.virtual:
|
||||
providers = [spec.name for spec in answer.values()
|
||||
if spec.package.provides(key)]
|
||||
key = providers[0]
|
||||
|
||||
self._concrete_specs.append(answer[key])
|
||||
|
||||
return self._concrete_specs
|
||||
|
||||
|
||||
def _normalize_packages_yaml(packages_yaml):
|
||||
normalized_yaml = copy.copy(packages_yaml)
|
||||
|
@ -329,7 +362,7 @@ def solve(
|
|||
timer.phase("ground")
|
||||
|
||||
# With a grounded program, we can run the solve.
|
||||
result = Result()
|
||||
result = Result(specs)
|
||||
models = [] # stable models if things go well
|
||||
cores = [] # unsatisfiable cores if they do not
|
||||
|
||||
|
|
|
@ -2561,3 +2561,15 @@ def test_multiple_modules_post_env_hook(tmpdir, install_mockery, mock_fetch):
|
|||
|
||||
assert view_prefix not in full_contents
|
||||
assert spec.prefix in full_contents
|
||||
|
||||
|
||||
@pytest.mark.regression('24148')
|
||||
def test_virtual_spec_concretize_together(tmpdir):
|
||||
# An environment should permit to concretize "mpi"
|
||||
e = ev.create('virtual_spec')
|
||||
e.concretization = 'together'
|
||||
|
||||
e.add('mpi')
|
||||
e.concretize()
|
||||
|
||||
assert any(s.package.provides('mpi') for _, s in e.concretized_specs())
|
||||
|
|
Loading…
Reference in a new issue