调试minizinc(无论如何,我发现了一个bug吗?)

时间:2015-01-22 14:38:35

标签: minizinc gecode

我熟悉MiniZinc的基础知识。因此,使用MiniZinc IDE,我写了像

这样的片段
solve satisfy;

string: s1 = "hello";
string: s2 = "world";

function list of int: cdr(list of int: v) =
  [v[i] | i in 1..length(v)];
function list of string: cdr(list of string: v) =
  [v[i] | i in 1..length(v)];

function string: concat(list of string: V) =
  if length(V) == 0 then "" else V[0] ++ concat(cdr(V)) endif;

output [concat([s1," ",s2])++" "++show(cdr([1,2,3]))];

显示

Compiling hello.mzn
Running hello.mzn
hello world [1, 2, 3]
----------
Finished in 49msec

现在,一个int列表的cdr似乎是错误的。我认为这是我的错误,虽然我无法发现它。

assertions可以帮助我吗? 由于我将使用Gecode(然后我有Gist)来实际将我的代码投入生产,我可以遵循这条路线吗?

任何暗示都赞赏......

编辑此代码段

solve satisfy;

function list of string: cdr_s(list of string: v) =
  [v[i] | i in 2..length(v)];

function string: vcat(list of string: V) =
  if length(V) == 0 then "" else V[1] ++ vcat(cdr_s(V)) endif;

output [vcat(["hello"," ","world"])];

报告

MiniZinc: type error: no function or predicate with this signature found: `cdr_s(array[int] of string)'
/tmp/MiniZinc IDE-9nYiuF/hello.ozn:2

2 个答案:

答案 0 :(得分:3)

我对您认为的错误以及其他一些问题感到有些困惑。

" cdr([1,2,3])"模型的输出似乎很好。给予" [1,2,3]"。名字" cdr"表明你想要"但首先"函数,但MiniZinc是一个默认的基于1的系统(不是从0开始)所以你的函数应该是

 function list of int: cdr(list of int: v) =
   [v[i] | i in 2..length(v)];

由于可以定义数组的索引(例如,起始索引为0),因此更为一般的定义(我对此并不满意,但您可能得到我的观点):

function list of int: cdr3(list of int: v) =
   [v[i] | i in index_set(v) diff {min(index_set(v))}];

所以现在你可以这样写:

% ...
array[int] of int: t = array1d(0..3, [1,2,3,4])
output [
   show(cdr3(t))
];

另外,你的" concat"函数根本没有使用,而是内置的" concat"它用了。 (尝试将您的版本重命名为" concat1"。)这也是为什么您没有为" V [0]"构造(应该给出超出界限的错误)。我原本预计尝试重新定义内置会产生错误,但MiniZinc 2.0在某些方面比版本1.6更宽松。

我同意阿克塞尔的一般性意见。作为一种通用编程语言,MiniZinc不是很令人印象深刻(至少在我的书中)。将约束和决策变量添加到模型时,真正的力量就来了。请注意,使用决策变量的MiniZinc列表/数组处理不像Prolog那样动态。通常,您应该始终将数组视为具有固定长度。

你开始研究MiniZinc真是太棒了。我希望这些评论在学习MiniZinc时能真正帮到你。

/哈坎

答案 1 :(得分:2)

MiniZinc是一个约束求解器而不是普通的编程语言。它知道变量和参数。您可以定义约束来界定形成解决方案的变量值的搜索空间。然后使用输出语句以格式化方式显示解决方案。

您的代码既不包含变量定义也不包含约束。 断言在MiniZinc中被用作特殊约束("约束断言")来检测无效参数。这类似于assert中的C/C++宏。

MiniZinc 2.0中引入了用户定义的函数,以更优雅的方式编写约束。也支持递归。

查看tutorialexamples

Hakan Kjellerstrand' s MiniZinc page也是一个很好的开始。

您的gecode代码指的是MiniZinc支持的解算器后端之一。 MiniZinc IDE允许选择后端。一些后端需要安装外部包。 MiniZinc编译器创建中间FlatZinc代码,最终由解算器后端之一解释和解决。