Какая польза от функции исправления minizinc? - PullRequest
0 голосов
/ 08 октября 2018

я вижу, что fix документация гласит:

http://www.minizinc.org/doc-lib/doc-builtins-reflect.html#Ifunction-dd-T-cl-fix-po-var-opt-dd-T-cl-x-pc

function array [$U] of $T: fix(array [$U] of var opt $T: x)
Check if the value of every element of the array x is fixedat this point in evaluation. If all are fixed, return an array of their values, otherwise abort.

Я думаю, что это можно использовать для приведения переменной к номиналу.Вот код

array [1..num]   of var int: value  ;
%% generate random numbers from 0..num-1, this should fix the value of the var "value"  or so i think
constraint forall(i in index_set(value))(let {int:temp_value=discrete_distribution([1|i in index_set(value)]); } in value[i]=trace(show(temp_value)++"\n", temp_value));

%%% this i was expecting to work, as "value" elements are fixed above
array [1..num]   of int:value__  =[ trace(show(fix(value[i])), fix(value[i])) | i in index_set(value)] ;

Но я получаю:

MiniZinc: evaluation error:
    with i = 1
  in call 'trace'
  in call 'fix'
  expression is not fixed

Мои вопросы:

1) Я думаю, что мне следует ожидать эту ошибку, поскольку minizinc не является языком последовательного выполнения?

2) Примеры fix в руководстве пользователя приведены только в том случае, когда используется оператор output.Это единственное место, где можно использовать fix?

3) Как бы я привел var к par?

Кстати, я пытаюсь преобразовать эту переменную в номинальнуюпотому что у меня возникли проблемы с выражением генератора массива.Вот код

int:num__=200;
int:seed=134;
int: two_m=2097184;
%% prepare weights for generating numbers form 1..(two_m div 64), basically same weight
array [1..(two_m div 64)] of int: value_6_wt= [seed+1 | i in 1..(two_m div 64)] ;
%% generate numbers. this dose not work gives out 
%% in variable declaration for 'value6'
%% parameter value out of range
array [1..num__] of int : value6 = [ discrete_distribution(value_6_wt) | j in 1..num__];

1 Ответ

0 голосов
/ 08 октября 2018

В языке MiniZinc разница между параметром и переменной заключается только в том, что параметр должен иметь значение во время компиляции.Внутри компилятора мы превращаем столько параметров в параметры, сколько можем.Это избавляет решателя от необходимости выполнять некоторую работу.Когда мы знаем, что переменная превращена в параметр, мы можем использовать функцию fix, чтобы убедить систему типов, что мы действительно можем использовать эту переменную в качестве параметра, и увидеть ее значение.

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

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

Выходной оператор и когда is_fixed возвращает true, будетоба дают гарантию того, что переменная исправлена, и гарантируют, что компиляция не прерывается.Нет другого способа привести переменную к параметру, но если вы не имеете дело с определениями зависимых предикатов, вы можете просто доверять компилятору MiniZinc, чтобы гарантировать, что результирующий FlatZinc будет содержать параметр вместо переменной.

...