Repository: spack/spack

Issue:
ASP-based solver: having more default values for mv variants is preferred to have new versions
Sometimes the ASP-based solver prefers to increase version badness, if that permits to use more defaults for multi-valued variants.

### Steps to reproduce the issue
This issue has been reported by @adamjstewart . With this configuration in `packages.yaml`:
```yaml
packages:
  all:
    variants: ~mpi
```
trying to concretize:
```console
$ spack solve gmt
==> Best of 11 considered solutions.
==> Optimization Criteria:
  Priority  Criterion                                  Value
  1         deprecated versions used                       0
  2         version weight                                 0
  3         number of non-default variants (roots)         0
  4         multi-valued variants                          0
  5         preferred providers for roots                  0
  6         number of non-default variants (non-roots)     0
  7         number of non-default providers (non-roots)   20
  8         count of non-root multi-valued variants       -2
  9         compiler mismatches                            0
  10        version badness                                7
  11        non-preferred compilers                        0
  12        target mismatches                              0
  13        non-preferred targets                          0

gmt@6.2.0%gcc@11.1.0~blas~docs~ffmpeg~fftw~gdal~ghostscript~glib~graphicsmagick~lapack~pcre arch=linux-ubuntu18.04-broadwell
    ^cmake@3.20.3%gcc@11.1.0~doc+ncurses+openssl+ownlibs~qt build_type=Release arch=linux-ubuntu18.04-broadwell
        ^ncurses@6.2%gcc@11.1.0~symlinks+termlib abi=none arch=linux-ubuntu18.04-broadwell
            ^pkgconf@1.7.4%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
        ^openssl@1.1.1k%gcc@11.1.0~docs+systemcerts arch=linux-ubuntu18.04-broadwell
            ^perl@5.34.0%gcc@11.1.0+cpanm+shared+threads arch=linux-ubuntu18.04-broadwell
                ^berkeley-db@18.1.40%gcc@11.1.0+cxx~docs+stl patches=b231fcc4d5cff05e5c3a4814f6a5af0e9a966428dc2176540d2c05aff41de522 arch=linux-ubuntu18.04-broadwell
                ^gdbm@1.19%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
                    ^readline@8.1%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
            ^zlib@1.2.11%gcc@11.1.0+optimize+pic+shared arch=linux-ubuntu18.04-broadwell
    ^curl@7.76.1%gcc@11.1.0~darwinssl~gssapi~libssh~libssh2~nghttp2 arch=linux-ubuntu18.04-broadwell
        ^libidn2@2.3.0%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
            ^libunistring@0.9.10%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
                ^libiconv@1.16%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
    ^netcdf-c@4.7.0%gcc@11.1.0~dap~fsync~hdf4~jna~mpi~parallel-netcdf+pic+shared patches=10a1c3f7fa05e2c82457482e272bbe04d66d0047b237ad0a73e87d63d848b16c arch=linux-ubuntu18.04-broadwell
        ^autoconf@2.69%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
            ^m4@1.4.19%gcc@11.1.0+sigsegv arch=linux-ubuntu18.04-broadwell
                ^libsigsegv@2.13%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
        ^automake@1.16.3%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
        ^hdf5@1.10.7%gcc@11.1.0~cxx~debug~fortran+hl~java~mpi+pic+shared~szip~threadsafe api=none arch=linux-ubuntu18.04-broadwell
        ^libtool@develop%gcc@11.1.0 patches=055fdac32f7768c44f64dfc18c183233a7909ff8b7556f67038350eed2056571 arch=linux-ubuntu18.04-broadwell
            ^help2man@1.47.16%gcc@11.1.0 arch=linux-ubuntu18.04-broadwell
            ^texinfo@6.5%gcc@11.1.0 patches=12f6edb0c6b270b8c8dba2ce17998c580db01182d871ee32b7b6e4129bd1d23a,1732115f651cff98989cb0215d8f64da5e0f7911ebf0c13b064920f088f2ffe1 arch=linux-ubuntu18.04-broadwell
            ^xz@5.2.5%gcc@11.1.0~pic libs=shared,static arch=linux-ubuntu18.04-broadwell
```
we obtain an old version of `netcdf-c` (the expected is 4.8.0). This is due to the fact that pulling in that old version permits to use more default values for multi-valued variants. This is preferred since mv variants is at priority 8 as opposed to version badness at priority 10.

### Information on your system

* **Spack:** 0.16.2-3053-e1bd3ae4db
* **Python:** 3.9.5
* **Platform:** linux-ubuntu18.04-broadwell
* **Concretizer:** clingo

### Additional information

- [x] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [x] I have searched the issues of this repo and believe this is not a duplicate
- [x] I have run the failing commands in debug mode and reported the output



Discussion:

Resolving patch:
diff --git a/var/spack/repos/builtin.mock/packages/gmt/package.py b/var/spack/repos/builtin.mock/packages/gmt/package.py
new file mode 100644
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/gmt/package.py
@@ -0,0 +1,10 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class Gmt(Package):
+
+    version('2.0', 'abcdef')
+    version('1.0', 'abcdef')
+
+    depends_on('mvdefaults', when='@1.0')
diff --git a/var/spack/repos/builtin.mock/packages/mvdefaults/package.py b/var/spack/repos/builtin.mock/packages/mvdefaults/package.py
new file mode 100644
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/mvdefaults/package.py
@@ -0,0 +1,10 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class Mvdefaults(Package):
+
+    version('1.0', 'abcdef')
+
+    variant('foo', values=('a', 'b', 'c'), default=('a', 'b', 'c'),
+            multi=True, description='')
diff --git a/var/spack/repos/builtin.mock/packages/root/package.py b/var/spack/repos/builtin.mock/packages/root/package.py
new file mode 100644
--- /dev/null
+++ b/var/spack/repos/builtin.mock/packages/root/package.py
@@ -0,0 +1,8 @@
+# Copyright 2013-2021 Lawrence Livermore National Security, LLC and other
+# Spack Project Developers. See the top-level COPYRIGHT file for details.
+#
+# SPDX-License-Identifier: (Apache-2.0 OR MIT)
+class Root(Package):
+    version('1.0', 'abcdef')
+
+    depends_on('gmt')


Test patch:
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -1244,3 +1244,12 @@ def test_deprecated_versions_not_selected(self, spec_str, expected):
 
         for abstract_spec in expected:
             assert abstract_spec in s
+
+    @pytest.mark.regression('24196')
+    def test_version_badness_more_important_than_default_mv_variants(self):
+        # If a dependency had an old version that for some reason pulls in
+        # a transitive dependency with a multi-valued variant, that old
+        # version was preferred because of the order of our optimization
+        # criteria.
+        s = spack.spec.Spec('root').concretized()
+        assert s['gmt'].satisfies('@2.0')