В языке MiniZinc разница между параметром и переменной заключается только в том, что параметр должен иметь значение во время компиляции.Внутри компилятора мы превращаем столько параметров в параметры, сколько можем.Это избавляет решателя от необходимости выполнять некоторую работу.Когда мы знаем, что переменная превращена в параметр, мы можем использовать функцию fix
, чтобы убедить систему типов, что мы действительно можем использовать эту переменную в качестве параметра, и увидеть ее значение.
Проблемаоднако здесь указывается, что fix
определено для прерывания, когда переменная не зафиксирована в одном значении.Если тестирование не проводится, это требует некоторых (волшебных) знаний о процессе компиляции.В вашем случае кажется, что второй массив оценивается до этапа оптимизации, на котором все псевдонимы разрешены.Это причина, почему это не работает.(Это действительно одна из вещей, которая является следствием декларативного языка)
Хотя fix
может использоваться только в выходных операторах в примерах (где он гарантированно работает), он используется вмного мест в библиотеках MiniZinc.Например, если мы посмотрим на библиотеку, которая используется для решателей MIP, существует много ограничений, которые можно кодировать более эффективно, если один из аргументов является параметром.Поэтому вы часто будете видеть, что ограничение в этой библиотеке сначала проверяет свои аргументы с is_fixed
, а затем использует лучшую кодировку, если это возвращает true.
Выходной оператор и когда is_fixed
возвращает true, будетоба дают гарантию того, что переменная исправлена, и гарантируют, что компиляция не прерывается.Нет другого способа привести переменную к параметру, но если вы не имеете дело с определениями зависимых предикатов, вы можете просто доверять компилятору MiniZinc, чтобы гарантировать, что результирующий FlatZinc будет содержать параметр вместо переменной.