0:00

So welcome to the reference section on Strings and Output.

So strings in MiniZinc are principally for output.

They can also be used in debugging constructs such as assertions and tracing.

But the key thing is that they can only be fixed.

Basically, we're not going to ask the solver to determine some strings.

So a string constant is wrapped in double quote characters.

It can contain Unicode characters, new line and tab using the C-style approach.

We can have a double quote character itself by putting a backslash beforehand.

And then, a backslash parenthesis and

then a MiniZinc expression then close parenthesis will basically add a string

which gives you the value of that MiniZinc expression in the middle of your string.

So this is an interpolated string value.

So there are a number of builtin string operations.

The show takes an arbitrary MiniZinc expression and

returns a string giving the value of the expression.

And that's exactly the same thing that happens in the interpolated string,

except that interpolated string is already inside another string.

We've got some formatted output for numbers.

So show_int here takes a first argument i, which its absolute value

is the minimum number of characters we're going to use to show the integer i.

If it's positive, then we're going to show it right justified, if it's negative,

we're going to show it left justified.

And show_float is similar.

Here we have this absolute value i.

This value i gives you the minimum number of characters we're going to use.

j gives you the number of digits after this point.

And justification ends on the sign of i.

So let's have a look at some examples of string functions.

So here we've got an enumerated type and some values, integer values and

float values.

If we have to show the value of this enumerated type p,

we just get the pink, the string that names the enumerated part.

If we're going to show the integer value 5 in -3, so

at least three characters, right justified, we get 5 and two spaces.

We're going to show a float value using five characters,

left justified with two things after this midpoint.

So this natural logarithm of 10.0,

we're going to get this space 2.30, so five characters.

Other string functions are concatenation, where we concatenate two strings together.

Or concatenate, which takes an array of strings and

concatenates them all together.

Or join, which is very similar to concatenate, but

adds a separator between each pair of strings we're concatenating together.

So if we take Hello and World, concatenate them, we get this string.

Concatenate the results, a, b, c from our previous example, we get pink.

5 gets two spaces, the space, and 2.30.

It's easy to see the three different strings if we use the join.

So adding the separator in between each of these, pink, that's a.

And there's the separator, then 5 with its two spaces, that was b.

And then the separator, then the space 2.30, which was c.

2:59

An output item is a list of strings, and basically it's going to take that list of

strings, concatenate them all together, and send them to the output.

There can be at most one output segment in the model.

And if there's no output segment, then all the declared variables in the model

that aren't equated to a right-hand side expression will be output as assignments.

So what's that mean?

Let's have a look at this model.

We've got three decision variables x, y and z.

But y was equated to a value when we declared it.

So the output will only include the values for x is 3 and z is 1.

So that's the solution for these constraints.

And notice the output is basically uniform,

which could be used as a MiniZinc dataform.

So we can do more complicated outputs.

So for example,

if you want to output a multi-dimensional array like this one here, a.

We'd like to show it in two dimensions, so we might use show_int 2 to make sure

that the sizes of each of these numbers are the same.

And we're going to do this extra thing, because when j is 3, so

when we get to the end of each row, we're going to add a new line.

Otherwise, we're going to have a space.

So basically, we're going to add the space between each two elements in the row,

and add a newline at the end.

And if you think about what this whole thing, this creates, is this.

So we've got space 5, which is showing the 5.

And then a space added by this if then else endif statement.

Then space 3, which is the result of this, and

the space added by this statement here.

Then 12, which is the show_int of 12.

And then a new line added by this statement.

And then some more space, 6, space, there's 2, space, there's 0, new line.

It's just going to print out like that, a nice aligned array.

So in output statements, every expression which isn't wrapped in show or

one of its variants, which is like show_int, show_float,

interpolated strings, has to be fixed.

So basically, once we get to the output, the solver needs to have already run,

we can't have any variables which aren't known to be fixed.

So we can ensure the variable's fixed using this fix built-in function.

So fix takes an expression, and it aborts if the expression does not have a fixed

value, and otherwise returns the fixed value.

So basically, this is mainly useful in output.

You can use it in general in models otherwise, but

usually it's either always going to abort or do something unuseful.

So if we look at this model here, we've got two variables, x and y,

which we're using.

So we're only showing this i, which is a parameter anyway, so

there's no problem there.

But we're using x and y here, and these are variables.

So basically, we're testing against the variable.

So in order for the output to be satisfied to know that it won't need to ask

the solver anything about this expression, we need to make sure that we actually wrap

these uses of variables by this fix x and fix y.

And of course, by the time we hit here, the solver has run, and

x should have a fixed value and y should have a fixed value in all cases.

And so this will always pass.

So basically, this fixes telling the output statement, or

MiniZinc that the output statement, that these values will be used in a fixed way.

We can take a little bit more complicated examples of output.

So imagine we had some tasks, and we had some starts and duration.

And presumably,

one of these would have been presumably a variable that's been solved by the solver.

We want print out a sort of, showing a graphical example of our output.

So we can print out the name and colon, and

then we could print out a number of spaces to get us to the column of the start time.

6:36

And then if the duration is 1, we're just going to print out this H character,

saying [INAUDIBLE] that time.

And otherwise, we're going to print out number of dashes which is

the duration minus 2, so that's where the task is running, right.

We're going to print out the start of the task at this point,

the dashes where the task is running, and the end of the task at this point.

And then a new line up here.

And if we take this down to here and run this, we're going to get here, well,

the open task begins at 0, has duration 3, so either it starts, running, ends.

Read begins at time 2, second time point.

It runs for duration 6, so it goes up to there.

Fix begins at time 5 and ends at time 6, so we've got the dashes in between.

Study starts at time 3 and only goes for one, so we use this H character,

say it starts and ends at the same place, and [INAUDIBLE].

So, strings in MiniZinc allow us to print the result of the model.

They're also useful when we're using the JSON output of MiniZinc

to connect to a website, for example.

And the key functions are really show and fix and concatenation.

And so you can end up with fairly complicated output statements if you want

to display something complicated.

And really, if you want to build a very, very complicated output,

you're better off to build a program in another language to

convert a simple output from MiniZinc to a complex output.

For example, outputting a JSON string in MiniZinc and

then using something to process that into some more complicated form.

That brings us to the end of strings and output.