Finds a set of dependencies that match the root package's constraints,
        or raises an error if no such set is available.

def solve(self):  # type: () -> SolverResult
        """
        Finds a set of dependencies that match the root package's constraints,
        or raises an error if no such set is available.
        """
        start = time.time()
        root_dependency = Dependency(self._root.name, self._root.version)
        root_dependency.is_root = True

        self._add_incompatibility(
            Incompatibility([Term(root_dependency, False)], RootCause())
        )

        try:
            next = self._root.name
            while next is not None:
                self._propagate(next)
                next = self._choose_package_version()

            return self._result()
        except Exception:
            raise
        finally:
            self._log(
                "Version solving took {:.3f} seconds.\n"
                "Tried {} solutions.".format(
                    time.time() - start, self._solution.attempted_solutions
                )
            )