From e6442557704840ad0f577747aa7f1195931585c9 Mon Sep 17 00:00:00 2001 From: Massimiliano Culpo Date: Wed, 16 Dec 2020 16:14:58 +0100 Subject: concretizer: emit facts for constraints on imposed dependencies --- lib/spack/spack/solver/asp.py | 37 +++++++--------- lib/spack/spack/solver/concretize.lp | 86 +++++++++++++++++++++++++++++------- 2 files changed, 85 insertions(+), 38 deletions(-) (limited to 'lib') diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py index e07cc92ae6..e6187f55f8 100644 --- a/lib/spack/spack/solver/asp.py +++ b/lib/spack/spack/solver/asp.py @@ -496,6 +496,7 @@ class SpackSolverSetup(object): # id for dummy variables self.card = 0 + self._condition_id_counter = 0 # Caches to optimize the setup phase of the solver self.target_specs_cache = None @@ -729,16 +730,16 @@ class SpackSolverSetup(object): def package_dependencies_rules(self, pkg, tests): """Translate 'depends_on' directives into ASP logic.""" for _, conditions in sorted(pkg.dependencies.items()): - for cond_id, (cond, dep) in enumerate(sorted(conditions.items())): + for cond, dep in sorted(conditions.items()): + global_condition_id = self._condition_id_counter + self._condition_id_counter += 1 named_cond = cond.copy() named_cond.name = named_cond.name or pkg.name # each independent condition has an id - self.gen.fact( - fn.dependency_condition( - dep.pkg.name, dep.spec.name, cond_id - ) - ) + self.gen.fact(fn.dependency_condition( + dep.pkg.name, dep.spec.name, global_condition_id + )) for t in sorted(dep.type): # Skip test dependencies if they're not requested at all @@ -751,19 +752,14 @@ class SpackSolverSetup(object): continue # there is a declared dependency of type t - self.gen.fact( - fn.declared_dependency(dep.pkg.name, dep.spec.name, cond_id, t) - ) + self.gen.fact(fn.dependency_type(global_condition_id, t)) # if it has conditions, declare them. conditions = self.spec_clauses(named_cond, body=True) for cond in conditions: - self.gen.fact( - fn.dep_cond( - dep.pkg.name, dep.spec.name, cond_id, - cond.name, *cond.args - ) - ) + self.gen.fact(fn.required_dependency_condition( + global_condition_id, cond.name, *cond.args + )) # add constraints on the dependency from dep spec. @@ -783,13 +779,9 @@ class SpackSolverSetup(object): else: clauses = self.spec_clauses(dep.spec) for clause in clauses: - self.gen.rule( - clause, - self.gen._and( - fn.depends_on(dep.pkg.name, dep.spec.name), - *self.spec_clauses(named_cond, body=True) - ) - ) + self.gen.fact(fn.imposed_dependency_condition( + global_condition_id, clause.name, *clause.args + )) self.gen.newline() @@ -1382,6 +1374,7 @@ class SpackSolverSetup(object): specs (list): list of Specs to solve """ + self._condition_id_counter = 0 # preliminary checks check_packages_exist(specs) diff --git a/lib/spack/spack/solver/concretize.lp b/lib/spack/spack/solver/concretize.lp index 234243523e..233de6f58e 100644 --- a/lib/spack/spack/solver/concretize.lp +++ b/lib/spack/spack/solver/concretize.lp @@ -56,32 +56,86 @@ depends_on(Package, Dependency, Type) % if any individual condition below is true, trigger the dependency. dependency_conditions(P, D, T) :- - dependency_conditions_hold(P, D, I), declared_dependency(P, D, I, T). + dependency_conditions_hold(P, D, I), + dependency_type(I, T). -% collect all the dependency condtions into a single conditional rule -dependency_conditions_hold(P, D, I) :- - node(Package) - : dep_cond(P, D, I, "node", Package); +% collect all the dependency conditions into a single conditional rule +dependency_conditions_hold(Package, Dependency, ID) :- version(Package, Version) - : dep_cond(P, D, I, "version", Package, Version); + : required_dependency_condition(ID, "version", Package, Version); version_satisfies(Package, Constraint) - : dep_cond(P, D, I, "version_satisfies", Package, Constraint); + : required_dependency_condition(ID, "version_satisfies", Package, Constraint); node_platform(Package, Platform) - : dep_cond(P, D, I, "node_platform", Package, Platform); + : required_dependency_condition(ID, "node_platform", Package, Platform); node_os(Package, OS) - : dep_cond(P, D, I, "node_os", Package, OS); + : required_dependency_condition(ID, "node_os", Package, OS); node_target(Package, Target) - : dep_cond(P, D, I, "node_target", Package, Target); + : required_dependency_condition(ID, "node_target", Package, Target); variant_value(Package, Variant, Value) - : dep_cond(P, D, I, "variant_value", Package, Variant, Value); + : required_dependency_condition(ID, "variant_value", Package, Variant, Value); node_compiler(Package, Compiler) - : dep_cond(P, D, I, "node_compiler", Package, Compiler); + : required_dependency_condition(ID, "node_compiler", Package, Compiler); node_compiler_version(Package, Compiler, Version) - : dep_cond(P, D, I, "node_compiler_version", Package, Compiler, Version); + : required_dependency_condition(ID, "node_compiler_version", Package, Compiler, Version); node_flag(Package, FlagType, Flag) - : dep_cond(P, D, I, "node_flag", Package, FlagType, Flag); - dependency_condition(P, D, I); - node(P). + : required_dependency_condition(ID, "node_flag", Package, FlagType, Flag); + dependency_condition(Package, Dependency, ID); + node(Package). + +% Implications from matching a dependency condition +node(Dependency) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency). + +version(Dependency, Version) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "version", Dependency, Version). + +version_satisfies(Dependency, Constraint) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "version_satisfies", Dependency, Constraint). + +node_platform(Dependency, Platform) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_platform", Dependency, Platform). + +node_os(Dependency, OS) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_os", Dependency, OS). + +node_target(Dependency, Target) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_target", Dependency, Target). + +variant_set(Dependency, Variant, Value) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "variant_set", Dependency, Variant, Value). + +node_compiler(Dependency, Compiler) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_compiler", Dependency, Compiler). + +node_compiler_version(Dependency, Compiler, Version) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_compiler_version", Dependency, Compiler, Version). + +node_compiler_version_satisfies(Dependency, Compiler, Version) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_compiler_version_satisfies", Dependency, Compiler, Version). + +node_flag(Dependency, FlagType, Flag) :- + dependency_conditions_hold(Package, Dependency, ID), + depends_on(Package, Dependency), + imposed_dependency_condition(ID, "node_flag", Dependency, FlagType, Flag). % if a virtual was required by some root spec, one provider is in the DAG 1 { node(Package) : provides_virtual(Package, Virtual) } 1 -- cgit v1.2.3-60-g2f50