Minizinc 嵌套输出循环

Minizinc nested output loop

我正在尝试编写一个带有嵌套循环的输出语句,并在外层输出非平凡的输出。如果 Minizinc 有一个顶级 for 命令,我会做类似

for (f in Foo) (
  output(["Foo: ", f])
  for (b in Bar) (
    for (q in Quz) (
      output([myArray[f,b,q], " "]);
    )
    output(["\n"]);
  )
  output(["\n"]);
)

所以如果

myArray = [[[1,2], [3,4]], [[5,6], [7,8]]];

它会输出

Foo: 1
1 2
3 4

Foo: 2
5 6
7 8

我想我可以用

之类的东西来做到这一点
output(if (b = 1 /\ q = 1) then "Foo: " ++ show(f) else "" endif ++
       show(myArray[f,b,q] ++ " " ++
       if (<maximum q>) <newline> ++
       if (<maximum q and maximum b>) <newline>
       | f in Foo, b in Bar, q in Quz);

但这看起来很尴尬(我的第一次尝试没有成功)。

我看到了 这是不同的,因为所有的输出都在最内层的循环中。我也想在外循环中输出。

我认为已接受答案的更清晰版本是

output [
  "Foo: \(f)\n"
  ++ concat(
       concat([show(myArray[f,b,q]) ++ " " | q in Quz])
         ++ "\n"
       | b in Bar])
  ++ "\n"
| f in Foo];

这避免了 if/then/else 构造,并清楚地表明我们正在为每个内部循环添加额外的输出 before/after。

如您所说:MiniZinc 输出语句可能有点笨拙。输出语句由关键字 output 后跟字符串数组组成。在很多情况下,我们希望使用 for 循环,但是在像 MiniZinc 这样的声明式语言中,这种控制流结构是不可用的。

您已经提供了解决方案:数组解析!看起来你几乎就在那里,但你的语法有点不对劲,你可能不理解它们的实际工作原理。数组理解类似于 for 循环,因为它确实遍历集合中的所有值。但是,它的不同之处在于它不仅执行循环中的语句,而且对它们进行求值,并且所有结果都需要是同一类型,在本例中为字符串。

你写的输出语句可以这样写:

output [
  "Foo: \(f)\n"
  ++ concat(["\(myArray[f,b,q])"
    ++ if q == max(Quz
      then "\n"
      else " "
    endif
  |b in Bar, q in Quz])
  ++ "\n"
| f in Foo];