私は、次のMiniZinc
のコードサンプルがあります。もともとy
があることを宣言されたことがわかり、ここでmzn2fzn変換中にintドメインセットを伝播する方法はありますか?
var set of 1..10: X_INTRODUCED_0_;
var set of 1..10: X_INTRODUCED_1_;
var set of 1..10: X_INTRODUCED_2_;
var set of 1..10: X_INTRODUCED_3_;
var set of 1..10: X_INTRODUCED_4_;
var set of 1..10: X_INTRODUCED_5_;
var set of 1..10: X_INTRODUCED_6_;
var -3..3: i:: output_var;
var set of 1..10: y:: output_var;
var 1..7: X_INTRODUCED_9_ ::var_is_introduced :: is_defined_var;
array [1..7] of var set of int: x:: output_array([-3..3]) = [X_INTRODUCED_0_,X_INTRODUCED_1_,X_INTRODUCED_2_,X_INTRODUCED_3_,X_INTRODUCED_4_,X_INTRODUCED_5_,X_INTRODUCED_6_];
constraint array_var_set_element(X_INTRODUCED_9_,[X_INTRODUCED_0_,X_INTRODUCED_1_,X_INTRODUCED_2_,X_INTRODUCED_3_,X_INTRODUCED_4_,X_INTRODUCED_5_,X_INTRODUCED_6_],y):: defines_var(y);
constraint int_lin_eq([1,-1],[i,X_INTRODUCED_9_],-4):: defines_var(X_INTRODUCED_9_):: domain;
solve satisfy;
:
include "globals.mzn";
var int: i;
array[-3..3] of var set of 1..10: x;
var set of 1..100: y;
constraint element(i, x, y);
solve satisfy;
output [
show(i), "\n",
show(x), "\n",
show(y), "\n",
];
標準ライブラリで実行mzn2fzn
コマンドは、以下のFlatZinc
コードを出力のモデルのset of 1..100
ですが、mzn2fzn
は配列x
の要素の境界をy
に正しく伝播しますFlatZinc
モデルはy
がset of 1..10
と宣言しています。
今、私は私自身の述語がelement_set
を使用した場合に呼び出されるので、次のように私がすることに変更されるようelement_set.mzn
の内容をカスタマイズしたい:
predicate element_set(var int: i, array[int] of var set of int: x,
var set of int: y) =
min(index_set(x)) <= i /\ i <= max(index_set(x)) /\
optimathsat_element_set(i, x, y, index_set(x));
predicate optimathsat_element_set(var int: i,
array[int] of var set of int: x,
var set of int: y,
set of int: xdom);
しかし、このコードはないます
predicate optimathsat_element_set(var int: i,array [int] of var set of int: x,var set of int: y,set of int: xdom);
var set of 1..10: X_INTRODUCED_0_;
var set of 1..10: X_INTRODUCED_1_;
var set of 1..10: X_INTRODUCED_2_;
var set of 1..10: X_INTRODUCED_3_;
var set of 1..10: X_INTRODUCED_4_;
var set of 1..10: X_INTRODUCED_5_;
var set of 1..10: X_INTRODUCED_6_;
var -3..3: i:: output_var;
var set of 1..100: y:: output_var; %%% OFFENSIVE LINE %%%
array [1..7] of var set of int: x:: output_array([-3..3]) = [X_INTRODUCED_0_,X_INTRODUCED_1_,X_INTRODUCED_2_,X_INTRODUCED_3_,X_INTRODUCED_4_,X_INTRODUCED_5_,X_INTRODUCED_6_];
constraint optimathsat_element_set(i,x,y,-3..3);
solve satisfy;
:得
FlatZinc
ファイル
y
がまだ
set of 1..100
であると宣言しているように、
y
に配列
x
の要素に境界を伝播します210
ドメインx
をy
に伝播するための正しいエンコード方法がわかっているかどうかを知りたいと思います。私は他のelement_T
の制約のためにこれを行うことができましたが、私は適切なの組み込みを見つけることができないので、element_set
の優雅な解決策を見つけることができません。。言い換えれば
、私はそれを行うだろうか
var set of 1..10: y:: output_var;
代わり
var set of 1..100: y:: output_var;
の取得したいですか?
ありがとうございます。私は既に 'array_var_set_element'を再定義しましたが、' SMT'ソルバの観点から、可能ならば 'element'をオーバーライドする方が良いです。 –
この回答は 'function element'に焦点を当てていますが、質問はグローバル制約ディレクトリの中に現れ、複雑な*構造を持たない' predicate element'に関するものでした。私は 'mzn_in_root_context'やこの*述語*をオーバーライドするのを心配する必要はないと推測するのは正しいですか? –
標準ライブラリの述部の実装には、関数の呼び出しが含まれています。人々が 'a [i] = y'と' element(i、a、y) 'を書く可能性が高いことを見て、述語の代わりに要素関数をオーバーライドすることをお勧めします。 – Dekker