summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/solver/asp.py83
-rw-r--r--lib/spack/spack/solver/concretize.lp166
-rw-r--r--lib/spack/spack/test/concretize.py4
3 files changed, 141 insertions, 112 deletions
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index e449b944ce..fe01be1bcf 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -302,6 +302,8 @@ class AspFunction(AspObject):
return clingo.String(str(arg))
elif isinstance(arg, int):
return clingo.Number(arg)
+ elif isinstance(arg, AspFunction):
+ return clingo.Function(arg.name, [argify(x) for x in arg.args], positive=positive)
else:
return clingo.String(str(arg))
@@ -918,16 +920,20 @@ class SpackSolverSetup:
)
for weight, declared_version in enumerate(most_to_least_preferred):
+ # TODO: self.package_fact(pkg.name).version_declared(declared_version, weight=weight)
self.gen.fact(
- fn.version_declared(
- pkg.name, declared_version.version, weight, str(declared_version.origin)
+ fn.facts(
+ pkg.name,
+ fn.version_declared(
+ declared_version.version, weight, str(declared_version.origin)
+ ),
)
)
# Declare deprecated versions for this package, if any
deprecated = self.deprecated_versions[pkg.name]
for v in sorted(deprecated):
- self.gen.fact(fn.deprecated_version(pkg.name, v))
+ self.gen.fact(fn.facts(pkg.name, fn.deprecated_version(v)))
def spec_versions(self, spec):
"""Return list of clauses expressing spec's version constraints."""
@@ -970,7 +976,9 @@ class SpackSolverSetup:
conflict_msg = default_msg.format(pkg.name, trigger, constraint)
constraint_msg = "conflict constraint %s" % str(constraint)
constraint_id = self.condition(constraint, name=pkg.name, msg=constraint_msg)
- self.gen.fact(fn.conflict(pkg.name, trigger_id, constraint_id, conflict_msg))
+ self.gen.fact(
+ fn.facts(pkg.name, fn.conflict(trigger_id, constraint_id, conflict_msg))
+ )
self.gen.newline()
def compiler_facts(self):
@@ -1023,8 +1031,11 @@ class SpackSolverSetup:
for i, compiler in enumerate(reversed(matches)):
self.gen.fact(
- fn.node_compiler_preference(
- pkg.name, compiler.spec.name, compiler.spec.version, -i * 100
+ fn.facts(
+ pkg.name,
+ fn.node_compiler_preference(
+ compiler.spec.name, compiler.spec.version, -i * 100
+ ),
)
)
@@ -1119,7 +1130,7 @@ class SpackSolverSetup:
if spack.spec.Spec() in when:
# unconditional variant
- self.gen.fact(fn.variant(pkg.name, name))
+ self.gen.fact(fn.facts(pkg.name, fn.variant(name)))
else:
# conditional variant
for w in when:
@@ -1128,19 +1139,23 @@ class SpackSolverSetup:
msg += " when %s" % w
cond_id = self.condition(w, name=pkg.name, msg=msg)
- self.gen.fact(fn.variant_condition(cond_id, pkg.name, name))
+ self.gen.fact(fn.facts(pkg.name, fn.conditional_variant(cond_id, name)))
single_value = not variant.multi
if single_value:
- self.gen.fact(fn.variant_single_value(pkg.name, name))
+ self.gen.fact(fn.facts(pkg.name, fn.variant_single_value(name)))
self.gen.fact(
- fn.variant_default_value_from_package_py(pkg.name, name, variant.default)
+ fn.facts(
+ pkg.name, fn.variant_default_value_from_package_py(name, variant.default)
+ )
)
else:
spec_variant = variant.make_default()
defaults = spec_variant.value
for val in sorted(defaults):
- self.gen.fact(fn.variant_default_value_from_package_py(pkg.name, name, val))
+ self.gen.fact(
+ fn.facts(pkg.name, fn.variant_default_value_from_package_py(name, val))
+ )
values = variant.values
if values is None:
@@ -1151,7 +1166,9 @@ class SpackSolverSetup:
for sid, s in enumerate(values.sets):
for value in s:
self.gen.fact(
- fn.variant_value_from_disjoint_sets(pkg.name, name, value, sid)
+ fn.facts(
+ pkg.name, fn.variant_value_from_disjoint_sets(name, value, sid)
+ )
)
union.update(s)
values = union
@@ -1178,7 +1195,9 @@ class SpackSolverSetup:
msg="empty (total) conflict constraint",
)
msg = "variant {0}={1} is conditionally disabled".format(name, value)
- self.gen.fact(fn.conflict(pkg.name, trigger_id, constraint_id, msg))
+ self.gen.fact(
+ fn.facts(pkg.name, fn.conflict(trigger_id, constraint_id, msg))
+ )
else:
imposed = spack.spec.Spec(value.when)
imposed.name = pkg.name
@@ -1189,10 +1208,10 @@ class SpackSolverSetup:
name=pkg.name,
msg="%s variant %s value %s when %s" % (pkg.name, name, value, when),
)
- self.gen.fact(fn.variant_possible_value(pkg.name, name, value))
+ self.gen.fact(fn.facts(pkg.name, fn.variant_possible_value(name, value)))
if variant.sticky:
- self.gen.fact(fn.variant_sticky(pkg.name, name))
+ self.gen.fact(fn.facts(pkg.name, fn.variant_sticky(name)))
self.gen.newline()
@@ -1210,7 +1229,8 @@ class SpackSolverSetup:
# virtual preferences
self.virtual_preferences(
- pkg.name, lambda v, p, i: self.gen.fact(fn.pkg_provider_preference(pkg.name, v, p, i))
+ pkg.name,
+ lambda v, p, i: self.gen.fact(fn.facts(pkg.name, fn.provider_preference(v, p, i))),
)
self.package_requirement_rules(pkg)
@@ -1232,7 +1252,7 @@ class SpackSolverSetup:
"""
named_cond = required_spec.copy()
named_cond.name = named_cond.name or name
- assert named_cond.name, "must provide name for anonymous condtions!"
+ assert named_cond.name, "must provide name for anonymous conditions!"
# Check if we can emit the requirements before updating the condition ID counter.
# In this way, if a condition can't be emitted but the exception is handled in the caller,
@@ -1240,7 +1260,8 @@ class SpackSolverSetup:
requirements = self.spec_clauses(named_cond, body=True, required_from=name)
condition_id = next(self._condition_id_counter)
- self.gen.fact(fn.condition(condition_id, msg))
+ self.gen.fact(fn.facts(named_cond.name, fn.condition(condition_id)))
+ self.gen.fact(fn.condition_reason(condition_id, msg))
for pred in requirements:
self.gen.fact(fn.condition_requirement(condition_id, *pred.args))
@@ -1259,13 +1280,15 @@ class SpackSolverSetup:
def package_provider_rules(self, pkg):
for provider_name in sorted(set(s.name for s in pkg.provided.keys())):
- self.gen.fact(fn.possible_provider(pkg.name, provider_name))
+ self.gen.fact(fn.facts(pkg.name, fn.possible_provider(provider_name)))
for provided, whens in pkg.provided.items():
for when in whens:
msg = "%s provides %s when %s" % (pkg.name, provided, when)
condition_id = self.condition(when, provided, pkg.name, msg)
- self.gen.fact(fn.provider_condition(condition_id, when.name, provided.name))
+ self.gen.fact(
+ fn.facts(when.name, fn.provider_condition(condition_id, provided.name))
+ )
self.gen.newline()
def package_dependencies_rules(self, pkg):
@@ -1291,7 +1314,9 @@ class SpackSolverSetup:
msg += " when %s" % cond
condition_id = self.condition(cond, dep.spec, pkg.name, msg)
- self.gen.fact(fn.dependency_condition(condition_id, pkg.name, dep.spec.name))
+ self.gen.fact(
+ fn.facts(pkg.name, fn.dependency_condition(condition_id, dep.spec.name))
+ )
for t in sorted(deptypes):
# there is a declared dependency of type t
@@ -1449,7 +1474,7 @@ class SpackSolverSetup:
for local_idx, spec in enumerate(external_specs):
msg = "%s available as external when satisfying %s" % (spec.name, spec)
condition_id = self.condition(spec, msg=msg)
- self.gen.fact(fn.possible_external(condition_id, pkg_name, local_idx))
+ self.gen.fact(fn.facts(pkg_name, fn.possible_external(condition_id, local_idx)))
self.possible_versions[spec.name].add(spec.version)
self.gen.newline()
@@ -1495,7 +1520,9 @@ class SpackSolverSetup:
if str(preferred.architecture.target) == best_default and i != 0:
offset = 100
self.gen.fact(
- fn.target_weight(pkg_name, str(preferred.architecture.target), i + offset)
+ fn.facts(
+ pkg_name, fn.target_weight(str(preferred.architecture.target), i + offset)
+ )
)
def spec_clauses(self, *args, **kwargs):
@@ -2041,11 +2068,11 @@ class SpackSolverSetup:
# generate facts for each package constraint and the version
# that satisfies it
for v in sorted(v for v in self.possible_versions[pkg_name] if v.satisfies(versions)):
- self.gen.fact(fn.version_satisfies(pkg_name, versions, v))
+ self.gen.fact(fn.facts(pkg_name, fn.version_satisfies(versions, v)))
self.gen.newline()
- def define_virtual_constraints(self):
+ def collect_virtual_constraints(self):
"""Define versions for constraints on virtuals.
Must be called before define_version_constraints().
@@ -2131,7 +2158,7 @@ class SpackSolverSetup:
# spec_clauses(). We might want to order these facts by pkg and name
# if we are debugging.
for pkg, variant, value in self.variant_values_from_specs:
- self.gen.fact(fn.variant_possible_value(pkg, variant, value))
+ self.gen.fact(fn.facts(pkg, fn.variant_possible_value(variant, value)))
def _facts_from_concrete_spec(self, spec, possible):
# tell the solver about any installed packages that could
@@ -2280,10 +2307,8 @@ class SpackSolverSetup:
self.gen.h1("Variant Values defined in specs")
self.define_variant_values()
- self.gen.h1("Virtual Constraints")
- self.define_virtual_constraints()
-
self.gen.h1("Version Constraints")
+ self.collect_virtual_constraints()
self.define_version_constraints()
self.gen.h1("Compiler Version Constraints")
diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp
index f90aa872f8..7cf01e98b0 100644
--- a/lib/spack/spack/solver/concretize.lp
+++ b/lib/spack/spack/solver/concretize.lp
@@ -64,23 +64,23 @@ error(100, multiple_values_error, Attribute, Package)
% Versions are declared with a weight and an origin, which indicates where the
% version was declared (e.g. "package_py" or "external").
-version_declared(Package, Version, Weight) :- version_declared(Package, Version, Weight, _).
+facts(Package, version_declared(Version, Weight)) :- facts(Package, version_declared(Version, Weight, _)).
% We can't emit the same version **with the same weight** from two different sources
-:- version_declared(Package, Version, Weight, Origin1),
- version_declared(Package, Version, Weight, Origin2),
+:- facts(Package, version_declared(Version, Weight, Origin1)),
+ facts(Package, version_declared(Version, Weight, Origin2)),
Origin1 < Origin2,
internal_error("Two versions with identical weights").
% We cannot use a version declared for an installed package if we end up building it
-:- version_declared(Package, Version, Weight, "installed"),
+:- facts(Package, version_declared(Version, Weight, "installed")),
attr("version", Package, Version),
version_weight(Package, Weight),
not attr("hash", Package, _),
internal_error("Reuse version weight used for built package").
% versions are declared w/priority -- declared with priority implies declared
-version_declared(Package, Version) :- version_declared(Package, Version, _).
+facts(Package, version_declared(Version)) :- facts(Package, version_declared(Version, _)).
% a spec with a git hash version is equivalent to one with the same matched version
version_satisfies(Package, Constraint, HashVersion) :- version_satisfies(Package, Constraint, EquivalentVersion),
@@ -93,7 +93,7 @@ version_satisfies(Package, Constraint, HashVersion) :- version_satisfies(Package
% is not precisely one version chosen. Error facts are heavily optimized
% against to ensure they cannot be inferred when a non-error solution is
% possible
-{ attr("version", Package, Version) : version_declared(Package, Version) }
+{ attr("version", Package, Version) : facts(Package, version_declared(Version)) }
:- attr("node", Package).
% A virtual package may or may not have a version, but never has more than one
@@ -104,17 +104,17 @@ error(100, "Cannot select a single version for virtual '{0}'", Virtual)
% If we select a deprecated version, mark the package as deprecated
attr("deprecated", Package, Version) :-
attr("version", Package, Version),
- deprecated_version(Package, Version).
+ facts(Package, deprecated_version(Version)).
possible_version_weight(Package, Weight)
:- attr("version", Package, Version),
- version_declared(Package, Version, Weight).
+ facts(Package, version_declared(Version, Weight)).
% we can't use the weight for an external version if we don't use the
% corresponding external spec.
:- attr("version", Package, Version),
version_weight(Package, Weight),
- version_declared(Package, Version, Weight, "external"),
+ facts(Package, version_declared(Version, Weight, "external")),
not external(Package),
internal_error("External weight used for built package").
@@ -122,17 +122,17 @@ possible_version_weight(Package, Weight)
% and vice-versa
:- attr("version", Package, Version),
version_weight(Package, Weight),
- version_declared(Package, Version, Weight, "installed"),
+ facts(Package, version_declared(Version, Weight, "installed")),
build(Package),
internal_error("Reuse version weight used for build package").
:- attr("version", Package, Version),
version_weight(Package, Weight),
- not version_declared(Package, Version, Weight, "installed"),
+ not facts(Package, version_declared(Version, Weight, "installed")),
not build(Package),
internal_error("Build version weight used for reused package").
-1 { version_weight(Package, Weight) : version_declared(Package, Version, Weight) } 1
+1 { version_weight(Package, Weight) : facts(Package, version_declared(Version, Weight)) } 1
:- attr("version", Package, Version),
attr("node", Package).
@@ -141,24 +141,24 @@ possible_version_weight(Package, Weight)
% While this choice rule appears redundant with the initial choice rule for
% versions, virtual nodes with version constraints require this rule to be
% able to choose versions
-{ attr("version", Package, Version) : version_satisfies(Package, Constraint, Version) }
+{ attr("version", Package, Version) : facts(Package, version_satisfies(Constraint, Version)) }
:- attr("node_version_satisfies", Package, Constraint).
% If there is at least a version that satisfy the constraint, impose a lower
% bound on the choice rule to avoid false positives with the error below
-1 { attr("version", Package, Version) : version_satisfies(Package, Constraint, Version) }
+1 { attr("version", Package, Version) : facts(Package, version_satisfies(Constraint, Version)) }
:- attr("node_version_satisfies", Package, Constraint),
- version_satisfies(Package, Constraint, _).
+ facts(Package, version_satisfies(Constraint, _)).
% More specific error message if the version cannot satisfy some constraint
% Otherwise covered by `no_version_error` and `versions_conflict_error`.
error(10, "Cannot satisfy '{0}@{1}'", Package, Constraint)
:- attr("node_version_satisfies", Package, Constraint),
attr("version", Package, Version),
- not version_satisfies(Package, Constraint, Version).
+ not facts(Package, version_satisfies(Constraint, Version)).
attr("node_version_satisfies", Package, Constraint)
- :- attr("version", Package, Version), version_satisfies(Package, Constraint, Version).
+ :- attr("version", Package, Version), facts(Package, version_satisfies(Constraint, Version)).
#defined version_satisfies/3.
#defined deprecated_version/2.
@@ -175,22 +175,22 @@ attr("node_version_satisfies", Package, Constraint)
%-----------------------------------------------------------------------------
% conditions are specified with `condition_requirement` and hold when
% corresponding spec attributes hold.
-condition_holds(ID) :-
- condition(ID, _);
+condition_holds(ID, Package) :-
+ facts(Package, condition(ID));
attr(Name, A1) : condition_requirement(ID, Name, A1);
attr(Name, A1, A2) : condition_requirement(ID, Name, A1, A2);
attr(Name, A1, A2, A3) : condition_requirement(ID, Name, A1, A2, A3);
attr(Name, A1, A2, A3, A4) : condition_requirement(ID, Name, A1, A2, A3, A4).
-% condition_holds(ID) implies all imposed_constraints, unless do_not_impose(ID)
+% condition_holds(ID, Package) implies all imposed_constraints, unless do_not_impose(ID, Package)
% is derived. This allows imposed constraints to be canceled in special cases.
-impose(ID) :- condition_holds(ID), not do_not_impose(ID).
+impose(ID, Package) :- condition_holds(ID, Package), not do_not_impose(ID, Package).
% conditions that hold impose constraints on other specs
-attr(Name, A1) :- impose(ID), imposed_constraint(ID, Name, A1).
-attr(Name, A1, A2) :- impose(ID), imposed_constraint(ID, Name, A1, A2).
-attr(Name, A1, A2, A3) :- impose(ID), imposed_constraint(ID, Name, A1, A2, A3).
-attr(Name, A1, A2, A3, A4) :- impose(ID), imposed_constraint(ID, Name, A1, A2, A3, A4).
+attr(Name, A1) :- impose(ID, Package), imposed_constraint(ID, Name, A1).
+attr(Name, A1, A2) :- impose(ID, Package), imposed_constraint(ID, Name, A1, A2).
+attr(Name, A1, A2, A3) :- impose(ID, Package), imposed_constraint(ID, Name, A1, A2, A3).
+attr(Name, A1, A2, A3, A4) :- impose(ID, Package), imposed_constraint(ID, Name, A1, A2, A3, A4).
% we cannot have additional variant values when we are working with concrete specs
:- attr("node", Package), attr("hash", Package, Hash),
@@ -231,17 +231,17 @@ depends_on(Package, Dependency) :- attr("depends_on", Package, Dependency, _).
% concrete specs don't need to be resolved -- they arise from the concrete
% specs themselves.
dependency_holds(Package, Dependency, Type) :-
- dependency_condition(ID, Package, Dependency),
+ facts(Package, dependency_condition(ID, Dependency)),
dependency_type(ID, Type),
build(Package),
not external(Package),
- condition_holds(ID).
+ condition_holds(ID, Package).
% We cut off dependencies of externals (as we don't really know them).
% Don't impose constraints on dependencies that don't exist.
-do_not_impose(ID) :-
+do_not_impose(ID, Package) :-
not dependency_holds(Package, Dependency, _),
- dependency_condition(ID, Package, Dependency).
+ facts(Package, dependency_condition(ID, Dependency)).
% declared dependencies are real if they're not virtual AND
% the package is not an external.
@@ -281,9 +281,9 @@ error(100, "Cyclic dependency detected between '{0}' and '{1}' (consider changin
% Conflicts
%-----------------------------------------------------------------------------
error(1, Msg) :- attr("node", Package),
- conflict(Package, TriggerID, ConstraintID, Msg),
- condition_holds(TriggerID),
- condition_holds(ConstraintID),
+ facts(Package, conflict(TriggerID, ConstraintID, Msg)),
+ condition_holds(TriggerID, Package),
+ condition_holds(ConstraintID, Package),
not external(Package), % ignore conflicts for externals
not attr("hash", Package, _). % ignore conflicts for installed packages
@@ -312,7 +312,7 @@ attr("virtual_node", Virtual)
% If there's a virtual node, we must select one and only one provider.
% The provider must be selected among the possible providers.
-{ provider(Package, Virtual) : possible_provider(Package, Virtual) }
+{ provider(Package, Virtual) : facts(Package, possible_provider(Virtual)) }
:- attr("virtual_node", Virtual).
error(100, "Cannot find valid provider for virtual {0}", Virtual)
@@ -339,8 +339,8 @@ provider(Package, Virtual) :- attr("node", Package), virtual_condition_holds(Pac
% The provider provides the virtual if some provider condition holds.
virtual_condition_holds(Provider, Virtual) :-
- provider_condition(ID, Provider, Virtual),
- condition_holds(ID),
+ facts(Provider, provider_condition(ID, Virtual)),
+ condition_holds(ID, Provider),
virtual(Virtual).
% A package cannot be the actual provider for a virtual if it does not
@@ -374,7 +374,7 @@ possible_provider_weight(Dependency, Virtual, 0, "external")
possible_provider_weight(Dependency, Virtual, Weight, "packages_yaml")
:- provider(Dependency, Virtual),
depends_on(Package, Dependency),
- pkg_provider_preference(Package, Virtual, Dependency, Weight).
+ facts(Package, provider_preference(Virtual, Dependency, Weight)).
% A provider mentioned in the default configuration can use a weight
% according to its priority in the list of providers
@@ -408,7 +408,7 @@ possible_provider_weight(Dependency, Virtual, 100, "fallback") :- provider(Depen
% if a package is external its version must be one of the external versions
{ external_version(Package, Version, Weight):
- version_declared(Package, Version, Weight, "external") }
+ facts(Package, version_declared(Version, Weight, "external")) }
:- external(Package).
error(100, "Attempted to use external for '{0}' which does not satisfy any configured external spec", Package)
:- external(Package),
@@ -436,7 +436,7 @@ external(Package) :- attr("external_spec_selected", Package, _).
% corresponding external spec.
:- attr("version", Package, Version),
version_weight(Package, Weight),
- version_declared(Package, Version, Weight, "external"),
+ facts(Package, version_declared(Version, Weight, "external")),
not external(Package),
internal_error("External weight used for internal spec").
@@ -447,7 +447,7 @@ attr("external_spec_selected", Package, LocalIndex) :-
not attr("hash", Package, _).
external_conditions_hold(Package, LocalIndex) :-
- possible_external(ID, Package, LocalIndex), condition_holds(ID).
+ facts(Package, possible_external(ID, LocalIndex)), condition_holds(ID, Package).
% it cannot happen that a spec is external, but none of the external specs
% conditions hold.
@@ -477,24 +477,24 @@ activate_requirement(Package, X) :-
activate_requirement(Package, X) :-
package_in_dag(Package),
requirement_group(Package, X),
- condition_holds(Y),
+ condition_holds(Y, Package),
requirement_conditional(Package, X, Y).
requirement_group_satisfied(Package, X) :-
- 1 { condition_holds(Y) : requirement_group_member(Y, Package, X) } 1,
+ 1 { condition_holds(Y, Package) : requirement_group_member(Y, Package, X) } 1,
requirement_policy(Package, X, "one_of"),
activate_requirement(Package, X),
requirement_group(Package, X).
requirement_weight(Package, Group, W) :-
- condition_holds(Y),
+ condition_holds(Y, Package),
requirement_has_weight(Y, W),
requirement_group_member(Y, Package, Group),
requirement_policy(Package, Group, "one_of"),
requirement_group_satisfied(Package, Group).
requirement_group_satisfied(Package, X) :-
- 1 { condition_holds(Y) : requirement_group_member(Y, Package, X) } ,
+ 1 { condition_holds(Y, Package) : requirement_group_member(Y, Package, X) } ,
requirement_policy(Package, X, "any_of"),
activate_requirement(Package, X),
requirement_group(Package, X).
@@ -514,7 +514,7 @@ requirement_group_satisfied(Package, X) :-
requirement_weight(Package, Group, W) :-
W = #min {
- Z : requirement_has_weight(Y, Z), condition_holds(Y), requirement_group_member(Y, Package, Group);
+ Z : requirement_has_weight(Y, Z), condition_holds(Y, Package), requirement_group_member(Y, Package, Group);
% We need this to avoid an annoying warning during the solve
% concretize.lp:1151:5-11: info: tuple ignored:
% #sup@73
@@ -549,8 +549,12 @@ error(10, Message) :-
%-----------------------------------------------------------------------------
% a variant is a variant of a package if it is a variant under some condition
% and that condition holds
-variant(Package, Variant) :- variant_condition(ID, Package, Variant),
- condition_holds(ID).
+node_has_variant(Package, variant(Variant)) :-
+ facts(Package, conditional_variant(ID, Variant)),
+ condition_holds(ID, Package).
+
+node_has_variant(Package, variant(Variant)) :- facts(Package, variant(Variant)).
+
attr("variant_propagate", Package, Variant, Value, Source) :-
attr("node", Package),
@@ -560,56 +564,56 @@ attr("variant_propagate", Package, Variant, Value, Source) :-
attr("variant_value", Package, Variant, Value) :-
attr("node", Package),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
attr("variant_propagate", Package, Variant, Value, _),
- variant_possible_value(Package, Variant, Value).
+ facts(Package, variant_possible_value(Variant, Value)).
error(100, "{0} and {1} cannot both propagate variant '{2}' to package {3} with values '{4}' and '{5}'", Source1, Source2, Variant, Package, Value1, Value2) :-
attr("variant_propagate", Package, Variant, Value1, Source1),
attr("variant_propagate", Package, Variant, Value2, Source2),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
Value1 < Value2.
% a variant cannot be set if it is not a variant on the package
error(100, "Cannot set variant '{0}' for package '{1}' because the variant condition cannot be satisfied for the given spec", Variant, Package)
:- attr("variant_set", Package, Variant),
- not variant(Package, Variant),
+ not node_has_variant(Package, variant(Variant)),
build(Package).
% a variant cannot take on a value if it is not a variant of the package
error(100, "Cannot set variant '{0}' for package '{1}' because the variant condition cannot be satisfied for the given spec", Variant, Package)
:- attr("variant_value", Package, Variant, _),
- not variant(Package, Variant),
+ not node_has_variant(Package, variant(Variant)),
build(Package).
% if a variant is sticky and not set its value is the default value
attr("variant_value", Package, Variant, Value) :-
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
not attr("variant_set", Package, Variant),
- variant_sticky(Package, Variant),
+ facts(Package, variant_sticky(Variant)),
variant_default_value(Package, Variant, Value),
build(Package).
% at most one variant value for single-valued variants.
{
attr("variant_value", Package, Variant, Value)
- : variant_possible_value(Package, Variant, Value)
+ : facts(Package, variant_possible_value(Variant, Value))
}
:- attr("node", Package),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
build(Package).
error(100, "'{0}' required multiple values for single-valued variant '{1}'", Package, Variant)
:- attr("node", Package),
- variant(Package, Variant),
- variant_single_value(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
+ facts(Package, variant_single_value(Variant)),
build(Package),
2 { attr("variant_value", Package, Variant, Value) }.
error(100, "No valid value for variant '{1}' of package '{0}'", Package, Variant)
:- attr("node", Package),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
build(Package),
not attr("variant_value", Package, Variant, _).
@@ -621,7 +625,7 @@ attr("variant_set", Package, Variant) :- attr("variant_set", Package, Variant, _
% have been built w/different variants from older/different package versions.
error(10, "'Spec({1}={2})' is not a valid value for '{0}' variant '{1}'", Package, Variant, Value)
:- attr("variant_value", Package, Variant, Value),
- not variant_possible_value(Package, Variant, Value),
+ not facts(Package, variant_possible_value(Variant, Value)),
build(Package).
% Some multi valued variants accept multiple values from disjoint sets.
@@ -630,8 +634,8 @@ error(10, "'Spec({1}={2})' is not a valid value for '{0}' variant '{1}'", Packag
error(100, "{0} variant '{1}' cannot have values '{2}' and '{3}' as they come from disjoint value sets", Package, Variant, Value1, Value2)
:- attr("variant_value", Package, Variant, Value1),
attr("variant_value", Package, Variant, Value2),
- variant_value_from_disjoint_sets(Package, Variant, Value1, Set1),
- variant_value_from_disjoint_sets(Package, Variant, Value2, Set2),
+ facts(Package, variant_value_from_disjoint_sets(Variant, Value1, Set1)),
+ facts(Package, variant_value_from_disjoint_sets(Variant, Value2, Set2)),
Set1 < Set2, % see[1]
build(Package).
@@ -639,7 +643,7 @@ error(100, "{0} variant '{1}' cannot have values '{2}' and '{3}' as they come fr
% we revert to the default value. If it is set, we force the set value
attr("variant_value", Package, Variant, Value)
:- attr("node", Package),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
attr("variant_set", Package, Variant, Value).
% The rules below allow us to prefer default values for variants
@@ -662,7 +666,7 @@ variant_not_default(Package, Variant, Value)
% A default variant value that is not used
variant_default_not_used(Package, Variant, Value)
:- variant_default_value(Package, Variant, Value),
- variant(Package, Variant),
+ node_has_variant(Package, variant(Variant)),
not attr("variant_value", Package, Variant, Value),
attr("node", Package).
@@ -670,7 +674,7 @@ variant_default_not_used(Package, Variant, Value)
external_with_variant_set(Package, Variant, Value)
:- attr("variant_value", Package, Variant, Value),
condition_requirement(ID, "variant_value", Package, Variant, Value),
- possible_external(ID, Package, _),
+ facts(Package, possible_external(ID, _)),
external(Package),
attr("node", Package).
@@ -682,7 +686,7 @@ external_with_variant_set(Package, Variant, Value)
% packages.yaml and the command line)
%
variant_default_value(Package, Variant, Value)
- :- variant_default_value_from_package_py(Package, Variant, Value),
+ :- facts(Package, variant_default_value_from_package_py(Variant, Value)),
not variant_default_value_from_packages_yaml(Package, Variant, _),
not attr("variant_default_value_from_cli", Package, Variant, _).
@@ -706,9 +710,11 @@ error(100, "{0} variant '{1}' cannot have values '{2}' and 'none'", Package, Var
% when assigned a value.
auto_variant("dev_path").
auto_variant("patches").
-variant(Package, Variant)
+
+node_has_variant(Package, variant(Variant))
:- attr("variant_set", Package, Variant, _), auto_variant(Variant).
-variant_single_value(Package, "dev_path")
+
+facts(Package, variant_single_value("dev_path"))
:- attr("variant_set", Package, "dev_path", _).
% suppress warnings about this atom being unset. It's only set if some
@@ -848,7 +854,7 @@ attr("node_target", Package, Target)
node_target_weight(Package, Weight)
:- attr("node", Package),
attr("node_target", Package, Target),
- target_weight(Package, Target, Weight).
+ facts(Package, target_weight(Target, Weight)).
% compatibility rules for targets among nodes
node_target_match(Parent, Dependency)
@@ -866,8 +872,6 @@ error(100, "'{0} target={1}' is not compatible with this machine", Package, Targ
attr("node_target", Package, Target),
not target(Target).
-#defined package_target_weight/3.
-
%-----------------------------------------------------------------------------
% Compiler semantics
%-----------------------------------------------------------------------------
@@ -981,18 +985,18 @@ compiler_weight(Package, Weight)
:- node_compiler(Package, CompilerID),
compiler_name(CompilerID, Compiler),
compiler_version(CompilerID, V),
- node_compiler_preference(Package, Compiler, V, Weight).
+ facts(Package, node_compiler_preference(Compiler, V, Weight)).
compiler_weight(Package, Weight)
:- node_compiler(Package, CompilerID),
compiler_name(CompilerID, Compiler),
compiler_version(CompilerID, V),
- not node_compiler_preference(Package, Compiler, V, _),
+ not facts(Package, node_compiler_preference(Compiler, V, _)),
default_compiler_preference(CompilerID, Weight).
compiler_weight(Package, 100)
:- node_compiler(Package, CompilerID),
compiler_name(CompilerID, Compiler),
compiler_version(CompilerID, V),
- not node_compiler_preference(Package, Compiler, V, _),
+ not facts(Package, node_compiler_preference(Compiler, V, _)),
not default_compiler_preference(CompilerID, _).
% For the time being, be strict and reuse only if the compiler match one we have on the system
@@ -1085,7 +1089,7 @@ attr("no_flags", Package, FlagType)
:- attr("node", Package), 2 { attr("hash", Package, Hash) }.
% if a hash is selected, we impose all the constraints that implies
-impose(Hash) :- attr("hash", Package, Hash).
+impose(Hash, Package) :- attr("hash", Package, Hash).
% if we haven't selected a hash for a package, we'll be building it
build(Package) :- not attr("hash", Package, _), attr("node", Package).
@@ -1124,7 +1128,7 @@ build_priority(Package, 0) :- attr("node", Package), not optimize_for_reuse().
% build deps in the solve, consider using them as a preference to resolve this.
:- attr("version", Package, Version),
version_weight(Package, Weight),
- version_declared(Package, Version, Weight, "installed"),
+ facts(Package, version_declared(Version, Weight, "installed")),
not optimize_for_reuse().
#defined installed_hash/2.
@@ -1339,10 +1343,10 @@ opt_criterion(5, "non-preferred targets").
#heuristic literal_solved(ID) : literal(ID). [50, init]
#heuristic attr("hash", Package, Hash) : attr("root", Package). [45, init]
-#heuristic attr("version", Package, Version) : version_declared(Package, Version, 0), attr("root", Package). [40, true]
-#heuristic version_weight(Package, 0) : version_declared(Package, Version, 0), attr("root", Package). [40, true]
+#heuristic attr("version", Package, Version) : facts(Package, version_declared(Version, 0)), attr("root", Package). [40, true]
+#heuristic version_weight(Package, 0) : facts(Package, version_declared(Version, 0)), attr("root", Package). [40, true]
#heuristic attr("variant_value", Package, Variant, Value) : variant_default_value(Package, Variant, Value), attr("root", Package). [40, true]
-#heuristic attr("node_target", Package, Target) : package_target_weight(Target, Package, 0), attr("root", Package). [40, true]
+#heuristic attr("node_target", Package, Target) : facts(Package, target_weight(Target, 0)), attr("root", Package). [40, true]
#heuristic node_target_weight(Package, 0) : attr("root", Package). [40, true]
#heuristic node_compiler(Package, CompilerID) : default_compiler_preference(ID, 0), compiler_id(ID), attr("root", Package). [40, true]
@@ -1350,10 +1354,10 @@ opt_criterion(5, "non-preferred targets").
#heuristic provider_weight(Package, Virtual, 0, R) : possible_provider_weight(Package, Virtual, 0, R), attr("virtual_node", Virtual). [30, true]
#heuristic attr("node", Package) : possible_provider_weight(Package, Virtual, 0, _), attr("virtual_node", Virtual). [30, true]
-#heuristic attr("version", Package, Version) : version_declared(Package, Version, 0), attr("node", Package). [20, true]
-#heuristic version_weight(Package, 0) : version_declared(Package, Version, 0), attr("node", Package). [20, true]
+#heuristic attr("version", Package, Version) : facts(Package, version_declared(Version, 0)), attr("node", Package). [20, true]
+#heuristic version_weight(Package, 0) : facts(Package, version_declared(Version, 0)), attr("node", Package). [20, true]
-#heuristic attr("node_target", Package, Target) : package_target_weight(Target, Package, 0), attr("node", Package). [20, true]
+#heuristic attr("node_target", Package, Target) : facts(Package, target_weight(Target, 0)), attr("node", Package). [20, true]
#heuristic node_target_weight(Package, 0) : attr("node", Package). [20, true]
#heuristic node_compiler(Package, CompilerID) : default_compiler_preference(ID, 0), compiler_id(ID), attr("node", Package). [15, true]
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index 465edfdb08..fad5812a2a 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -152,7 +152,7 @@ class Root(Package):
version("1.0", sha256="abcde")
depends_on("changing")
- conflicts("changing~foo")
+ conflicts("^changing~foo")
"""
packages_dir.join("root", "package.py").write(root_pkg_str, ensure=True)
@@ -1599,7 +1599,7 @@ class TestConcretize:
pytest.xfail("Known failure of the original concretizer")
# Install a dependency that cannot be reused with "root"
- # because of a conflict a variant, then delete its version
+ # because of a conflict in a variant, then delete its version
dependency = Spec("changing@1.0~foo").concretized()
dependency.package.do_install(fake=True, explicit=True)
repo_with_changing_recipe.change({"delete_version": True})