Некоторые языки программирования (например, haskell) допускают циклические зависимости между модули. Поскольку компилятору необходимо знать все определения всех модулей, импортированных при компиляции одного модуля, обычно ему приходится проделывать некоторую дополнительную работу, если некоторые модули взаимно импортируют друг друга или возникает какой-либо другой цикл. В этом случае компилятор не сможет оптимизировать код в такой степени, как в модулях, у которых нет циклов импорта, поскольку импортированные функции, возможно, еще не были проанализированы. Обычно таким образом компилируется только один модуль цикла, поскольку бинарный объект не имеет зависимостей. Назовем такой модуль прерыватель петель.
Особенно если циклы импорта чередуются, интересно знать, как минимизировать количество прерывателей цикла при компиляции большого проекта, состоящего из сотен модулей.
Существует ли алгоритм, который с заданным набором зависимостей выводит минимальное количество модулей, которые необходимо скомпилировать в качестве прерывателей цикла для успешной компиляции программы?
Пример
Я пытаюсь пояснить, что я имею в виду в этом примере.
Рассмотрим проект с четырьмя модулями A
, B
, C
и D
. Это список зависимостей между этими модулями, запись X y
означает, что y
зависит от x
:
A C A D B A C B D B
То же отношение, представленное в виде ASCII-диаграммы:
D ---> B ^ / ^ | / | | / | | L | A ---> C
В этом графике зависимостей есть два цикла: ADB
и ACB
. Чтобы разорвать эти циклы, можно, например, скомпилировать модули C
и D
как прерыватели цикла. Очевидно, это не лучший подход. Компиляции A
в качестве прерывателя цикла вполне достаточно, чтобы разорвать оба цикла, и вам нужно скомпилировать на один модуль меньше в качестве прерывателя цикла.