MiniZinc类型错误:array[int] of var opt string问题修复咨询
MiniZinc类型错误修复:invalid type for comprehension:
array[int] of var opt string 问题场景
我使用MiniZinc 2.7.6和Gecode 6.3.0运行以下代码:
int: user_property_1 = 1; % user_property_1-parameter int: user_property_2 = 2; % user_property_2-parameter int: user_property_3 = 1; % user_property_3-parameter int: user_property_4 = 2; % user_property_4-parameter int: user_property_5 = 2; % user_property_5-parameter int: user_property_6 = 1; % user_property_6-parameter int: user_property_7 = 1; % user_property_7-parameter array [1..3] of {0, 5, 10, 15, 20, 30}: product_property_1 = [5,10,15]; % product_property_1-parameter array [1..3] of {0, 3, 9, 12, 15, 20}: product_property_2 = [3,3,3]; % product_property_2-parameter array [1..3] of {0, 2, 24, 720}: product_property_3 = [0,0,0]; % product_property_3-parameter array [1..3] of {0, 1}: product_property_4 = [0,0,0]; % product_property_4-parameter array [1..3] of {0, 3, 9, 12, 15, 20}: product_property_5 = [0,0,0]; % product_property_5-parameter array [1..3] of {0, 3, 9, 12, 15, 20}: product_property_6 = [0,0,0]; % product_property_6-parameter array [1..3] of int: price = [61,77,91]; % price-parameter array [1..3] of {0, 1}: rides_limit = [0,0,0]; % rides_limit-parameter array [1..3] of string: object_ids = ["5eb4028e8f061c3338dd41b7","5eb4028e8f061c3338dd41b8","5eb4028e8f061c3338dd41b9"]; % object_ids-parameter var set of 1..3: occur; % occur-variable constraint user_property_1==2 ->forall (i in occur) (product_property_4 [i]= 0); % C1-constraint constraint user_property_4==3 ->forall (i in occur)(product_property_2 [i] != 0 ); % C2-constraint constraint user_property_3==3 ->forall (i in occur)(product_property_4[i]!=0); % C3-constraint constraint user_property_5==2 ->forall (i in occur)(product_property_3[i]!=0); % C4-constraint constraint user_property_6==3 ->forall (i in occur)(product_property_5[i]!=0); % C5-constraint constraint user_property_7==3 ->forall (i in occur)(product_property_6[i]!=0); % C6-constraint constraint user_property_2==3 ->forall (i in occur)(product_property_1[i]!=0); % C7-constraint solve satisfy; output["product_ids:" ++ join(",", [ "\(i)" | i in fix(occur)] ) ++"\nObject_ids:" ++show(i in occur) (object_ids[i])++"\nproduct_property_1:" ++show(i in occur) (product_property_1[i])++"\nproduct_property_2:" ++show(i in occur) (product_property_2[i])++"\nproduct_property_3:" ++show(i in occur) (product_property_3[i])++"\nproduct_property_4:" ++show(i in occur) (product_property_4[i])++"\nproduct_property_5:" ++show(i in occur) (product_property_5[i])++"\nproduct_property_6:" ++show(i in occur) (product_property_6[i])++"\nprice:" ++show(i in occur) (price[i])++"\nrides_limit:" ++show(i in occur) (rides_limit[i])++"\nnumber_products:"++ show(card(occur))++"\n" ]; % goal
错误信息
MiniZinc: type error: invalid type for comprehension:
array[int] of var opt string
问题分析
错误根源不在object_ids数组定义,而是输出语句中遍历集合occur的语法错误。原代码里show(i in occur) (xxx[i])的写法,在MiniZinc 2.7.x这类新版本中会触发严格的类型检查:因为occur是变量集合,直接这么取值会生成可选类型(opt)的数组,而输出逻辑无法直接处理这类类型。
你提到代码之前能运行,确实和版本有关:旧版本MiniZinc对集合遍历的输出语法兼容性更宽松,新版本收紧了类型规则,导致旧写法触发错误。
修复方案
把输出语句中所有show(i in occur) (xxx[i])的写法,改成和product_ids一致的列表推导式+join拼接形式,明确生成确定类型的字符串数组,避免可选类型问题。
修复后的完整输出语句如下:
output[ "product_ids:" ++ join(",", [ "\(i)" | i in fix(occur)] ) ++"\n" ++ "Object_ids:" ++ join(",", [ object_ids[i] | i in fix(occur)] ) ++"\n" ++ "product_property_1:" ++ join(",", [ "\(product_property_1[i])" | i in fix(occur)] ) ++"\n" ++ "product_property_2:" ++ join(",", [ "\(product_property_2[i])" | i in fix(occur)] ) ++"\n" ++ "product_property_3:" ++ join(",", [ "\(product_property_3[i])" | i in fix(occur)] ) ++"\n" ++ "product_property_4:" ++ join(",", [ "\(product_property_4[i])" | i in fix(occur)] ) ++"\n" ++ "product_property_5:" ++ join(",", [ "\(product_property_5[i])" | i in fix(occur)] ) ++"\n" ++ "product_property_6:" ++ join(",", [ "\(product_property_6[i])" | i in fix(occur)] ) ++"\n" ++ "price:" ++ join(",", [ "\(price[i])" | i in fix(occur)] ) ++"\n" ++ "rides_limit:" ++ join(",", [ "\(rides_limit[i])" | i in fix(occur)] ) ++"\n" ++ "number_products:"++ show(card(occur))++"\n" ];
关键修复点
- 用
[ xxx[i] | i in fix(occur) ]生成对应元素的列表,再通过join(",", ...)拼接成字符串 - 非字符串类型(比如数字)用
\(xxx[i])转成字符串后再加入列表 - 统一和
product_ids的写法逻辑,确保类型推导正确
补充说明
关于你尝试的枚举类型:枚举名称不能以数字开头,但可以给枚举值绑定带数字的字符串,比如:
enum ObjectEnum = O1 | O2 | O3; array[ObjectEnum] of string: object_ids_map = ["5eb4028e8f061c3338dd41b7", "5eb4028e8f061c3338dd41b8", "5eb4028e8f061c3338dd41b9"];
不过这次问题不需要枚举,修复输出语法就能解决。
内容的提问来源于stack exchange,提问作者user2829319
相关产品推荐
相关产品推荐

