concretizer: emit facts for constraints on imposed dependencies

This commit is contained in:
Massimiliano Culpo 2020-12-16 16:14:58 +01:00 committed by Tamara Dahlgren
parent 02e0ea6105
commit 364c5b636c
2 changed files with 85 additions and 38 deletions

View File

@ -496,6 +496,7 @@ def __init__(self):
# 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 @@ def pkg_rules(self, pkg, tests):
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 @@ def package_dependencies_rules(self, pkg, tests):
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 @@ def package_dependencies_rules(self, pkg, tests):
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()
@ -1383,6 +1375,7 @@ def setup(self, driver, specs, tests=False):
specs (list): list of Specs to solve
"""
self._condition_id_counter = 0
# preliminary checks
check_packages_exist(specs)

View File

@ -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