diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index 105efcd6cca..23e7141497b 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -1334,6 +1334,11 @@ def package_dependencies_rules(self, pkg): condition_id, "dependency_holds", pkg.name, dep.spec.name, t ) ) + self.gen.fact( + fn.imposed_constraint( + condition_id, "virtual_node" if dep.spec.virtual else "node", dep.spec.name + ) + ) self.gen.newline() diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index cdfea9883ae..24cff31cc85 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -294,9 +294,6 @@ attr("depends_on", Package, Dependency, Type) % every root must be a node attr("node", Package) :- attr("root", Package). -% dependencies imply new nodes -attr("node", Dependency) :- attr("node", Package), depends_on(Package, Dependency). - % all nodes in the graph must be reachable from some root % this ensures a user can't say `zlib ^libiconv` (neither of which have any % dependencies) and get a two-node unconnected graph @@ -341,10 +338,13 @@ attr("depends_on", Package, Provider, Type) provider(Provider, Virtual), not external(Package). -% dependencies on virtuals also imply that the virtual is a virtual node -attr("virtual_node", Virtual) +% If a package depends on a provider, the provider must be a node +% nodes that are not indirected by a virtual are instantiated +% directly from the imposed constraints of the dependency condition +attr("node", Provider) :- attr("dependency_holds", Package, Virtual, Type), - virtual(Virtual), not external(Package). + provider(Provider, Virtual), + not external(Package). % If there's a virtual node, we must select one and only one provider. % The provider must be selected among the possible providers.