concretizer: use conditional literals for versions.

This commit is contained in:
Todd Gamblin 2019-08-18 22:54:13 -07:00
parent 4288639770
commit 6bbc64555b
2 changed files with 30 additions and 23 deletions

View File

@ -159,9 +159,8 @@ def constraint(self, body):
def pkg_version_rules(self, pkg): def pkg_version_rules(self, pkg):
pkg = packagize(pkg) pkg = packagize(pkg)
self.rule( for v in pkg.versions:
self._or(fn.version(pkg.name, v) for v in pkg.versions), self.fact(fn.version_declared(pkg.name, v))
fn.node(pkg.name))
def spec_versions(self, spec): def spec_versions(self, spec):
spec = specify(spec) spec = specify(spec)
@ -170,23 +169,20 @@ def spec_versions(self, spec):
self.rule(fn.version(spec.name, spec.version), self.rule(fn.version(spec.name, spec.version),
fn.node(spec.name)) fn.node(spec.name))
else: else:
version = spec.versions versions = list(spec.package.versions)
impossible, possible = [], []
for v in spec.package.versions:
if v.satisfies(version):
possible.append(v)
else:
impossible.append(v)
if impossible: # if the spec declares a new version, add it to the
self.rule( # possibilities.
self._and(self._not(fn.version(spec.name, v)) if spec.versions.concrete and spec.version not in versions:
for v in impossible), self.fact(fn.version_declared(spec.name, spec.version))
fn.node(spec.name)) versions.append(spec.version)
if possible:
self.rule( # conflict with any versions that do not satisfy the spec
self._or(fn.version(spec.name, v) for v in possible), # TODO: need to traverse allspecs beforehand and ensure all
fn.node(spec.name)) # TODO: versions are known so we can disallow them.
for v in versions:
if not v.satisfies(spec.versions):
self.fact(fn.version_conflict(spec.name, v))
def compiler_defaults(self): def compiler_defaults(self):
"""Facts about available compilers.""" """Facts about available compilers."""

View File

@ -1,8 +1,20 @@
%============================================================================= %=============================================================================
% Generate % Generate
%============================================================================= %=============================================================================
%-----------------------------------------------------------------------------
% Version semantics
%-----------------------------------------------------------------------------
% If something is a package, it has only one version and that must be a
% possible version.
1 { version(P, V) : version_possible(P, V) } 1 :- node(P).
% If a version is declared but conflicted, it's not possible.
version_possible(P, V) :- version_declared(P, V), not version_conflict(P, V).
#defined version_conflict/2.
% One version, arch, etc. per package % One version, arch, etc. per package
{ version(P, V) : version(P, V)} = 1 :- node(P).
{ arch_platform(P, A) : arch_platform(P, A) } = 1 :- node(P). { arch_platform(P, A) : arch_platform(P, A) } = 1 :- node(P).
{ arch_os(P, A) : arch_os(P, A) } = 1 :- node(P). { arch_os(P, A) : arch_os(P, A) } = 1 :- node(P).
{ arch_target(P, T) : arch_target(P, T) } = 1 :- node(P). { arch_target(P, T) : arch_target(P, T) } = 1 :- node(P).
@ -92,9 +104,8 @@ node_compiler_version(P, C, V)
node_compiler_version_set(P, C, V). node_compiler_version_set(P, C, V).
% node compiler versions can only be from the available compiler versions % node compiler versions can only be from the available compiler versions
node_compiler_version(P, C, V) :- node(P), compiler(C), node_compiler(P, C), node_compiler_version(P, C, V),
:- node(P), compiler(C), node_compiler(P, C), not compiler_version(C, V).
compiler_version(C, V).
% if no compiler is set, fall back to default. % if no compiler is set, fall back to default.
node_compiler(P, C) node_compiler(P, C)