나는 다음 MiniZinc
코드 샘플이 있습니다mzn2fzn 변환 중 int 도메인 집합을 전파하는 방법은 무엇입니까?
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
코드 출력 : 여기에
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;
을 통지 원래 y
가 선언되었다 set of 1..100
MiniZinc
모델이지만 mzn2fzn
은 배열 x
의 요소에 대한 경계를 y
에 올바르게 전파하므로 FlatZinc
모델은 y
을 set of 1..10
으로 선언합니다.
지금, 나는 element_set.mzn
의 내용을 사용자 정의 할 수 있도록 내 자신의 술어를 사용하는 경우 element_set
이라고, 그래서 다음과 같이이로 변경됩니다 :
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;
,691,363 : 결과
FlatZinc
파일이
y
여전히
set of 1..100
선언했다, 그래서
y
에 배열
x
의 요소에 대한 경계를 전파210
의 도메인을 전파하는 데 올바른 인코딩이 무엇인지 알고있는 사람이 있는지 알고 싶습니다. 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