0:25

And then set expressions, well then we have set literals,

Â which are open brace and

Â then the elements separated by commas, and then close brace, that was a fixed set.

Â We've already seen how to build integer or

Â float ranges as sets using this dot dot notation.

Â And then the standard set operator is provided, so

Â in says whether this element is in the set or not.

Â Writes the elements to the set and union and

Â intersection of two sets are well understood.

Â We can test whether one subset is a subset or a superset of another.

Â We can also do set subtraction is different, so

Â A diff B gives you all the elements of A, which aren't in B.

Â And symmetric difference is rather like X also A,

Â symdiff B gives you all the elements in A and B, which aren't in both.

Â 1:20

And sets can be used as types, so we can declare a variable given a set.

Â Here's some examples of some fixed sets, so

Â this numbers 1 to 6 is a few of the small prime numbers.

Â Here's a float range, here's a fixed set of float numbers, and

Â here's a fixed set of Boolean values.

Â Obviously, there aren't many sets of bools which are very interesting, so

Â we don't use sets of bools very often.

Â 1:46

So let's look at some examples of set expressions.

Â So we can take ROW union PRIME, that's a union of two sets.

Â We can intersect two sets here, two sets of floats.

Â Here we're taking the symmetric difference of two sets.

Â Here we're checking if one set is a subset of another and

Â recording that result in Boolean.

Â And here we're building up a Boolean set,

Â which is going to have an element which is equal to is PRIME a subset of ROW.

Â And it's going to have the false element as well in that set.

Â So how do we evaluate those values?

Â 2:17

So we think of x ROW union PRIME.

Â Obviously, we're going to have the numbers 1 to 6 which is ROW,

Â plus the numbers 2, 3, 5, 7, 11, 13, which is PRIME.

Â So that's the union of those.

Â We look at range intersection NUM, so there are two numbers in NUM,

Â our 2.57, 2.87, and 3.14.

Â And the range is from 3.0 to 5.0, so only 3.14 exists

Â in that range, so that's the end of the intersection.

Â If we take ROW symdiff PRIME, and we need numbers that occur in 1 to 6,

Â and in 2, 3, 5, 7, 11, 13 exactly once.

Â And we get 1 which it occurs in the first one.

Â 2, occurs in both so we don't get that.

Â 3, it occurs in both, we don't get that.

Â 4 only goes until 6, so that we get that one.

Â 5, it goes in both 1 to 6, and 2, 3, 5, 7, 11, 13 so we don't get that.

Â And then 6, 7, 11, 13.

Â Is ROW a subset of PRIME?

Â Well, obviously not, because ROW takes the value of 1 which isn't in PRIME, so

Â that's just the value false.

Â We look at this set of Booleans, bs, is PRIME a subset of ROW?

Â No it's not, that's false, so we get this set of false and false.

Â But of course it's a set, so that's the same, same, the set containing false.

Â 3:37

Arrays are another critical data structure in MiniZinc and they could be multidimensional.

Â They're declared by this array and index_set1 and set index_set2

Â ..., as many index sets as I want.

Â Although typically, we don't go very far beyond three or

Â four normally, of some type.

Â Now the index set of your array needs to be either an integer range or

Â a fixed set expression whose value is an integer range.

Â Or a enumerated type range expression,

Â because enumerated types act very much like integers.

Â So the elements of the array, so

Â what this type here can be basically anything except another array.

Â And here an array, 2-D array, known by PRODUCT and RESOURCE of integers,

Â you would have 1-D array variables, maybe the production.

Â Taking values from 0 to mproducts.

Â An important array function which we use is length,

Â which returns the number of elements in a 1-D array.

Â 4:53

A 2-D array initialization can also be done,

Â it uses a special 2-D array notation.

Â So here we start the 2-D array with this open brace vertical bar and this

Â is the first row, separated by commas and we use a vertical bar to separate the row.

Â Here's the second row, separated by commas and

Â here's vertical bar end braces to end the two-dimensional array.

Â And arrays of any dimension less than or

Â equal to six can be initialized from a list.

Â So basically from 1-D array we can build up to a six-dimensional array using

Â the family of arraynd functions.

Â So another way of moving exactly the same consumption matrix would be to

Â take the 1-D array, which is all the values given in the same order and

Â say, well, we want this to be an array which has two rows and five columns.

Â And we're going to have these index sets from one to two and one to five.

Â We'll get exactly the same result with these.

Â We can use concatenation on one of the arrays.

Â And that's sometimes very useful to concatenate some arrays and

Â then use an array indeed to built the array for example.

Â 6:01

So a key thing that we're going to do with array and

Â set objects is build comprehensions.

Â So a set comprehension, as this expression, this is the expression

Â that's going to give the value of the current set and set of generators.

Â And we could have an optional where expression, which is

Â going to require that the generated variables take a particular value.

Â 6:23

And array comprehension is exactly the same,

Â just we're using it with the braces rather than its closed

Â brackets rather than the braces to say that this is an array, not a set.

Â The generators of this form, var in set-expression.

Â So this variable is going to take values from this specific expression.

Â And normally, we'd expect this set-expression to be fixed, right?

Â We can't have unfixed set-expressions here.

Â But if we do, then it's actually going to end up doing something behind the scenes,

Â which can cause you some difficulties if you don't know what's going on.

Â We'll talk about that more in the relations

Â mandates in the optional types section.

Â So an alternate syntax.

Â When you have two or more generators that use the same set is, we can have this v1,

Â v2 in set-expression, which is just shorthand for having v1 in set-expr,

Â followed by v2 in set-expr.

Â 7:29

Basically, you give a value to variable generator1.

Â With that, you can give a value to the variable of the generator2.

Â You keep doing that until you hit the end of all the generators.

Â And then you evaluate this Boolean expression with all those

Â generator values.

Â And if it evaluates to true you'd generate this expression here,

Â given the values that the generator builds.

Â Then you try the next value for the last generator.

Â 7:55

And you evaluate, again, this bool expression,

Â just check where they're called.

Â And generate a name and an expression in your array.

Â When that generator is exhausted, right, then you try the next or

Â last value for the previous generator.

Â And keep doing this until all the generators are exhausted.

Â But let's think about this on the simple example.

Â Here's a set comprehension.

Â But basically, we're going to do the array comprehension and

Â then convert it into a set because that's exactly how that goes.

Â 8:25

Now i takes its first value, which is 1 and

Â j takes its first value, which is 1 and then we test, is i less than j?

Â That doesn't hold, so we go back to j, which is the last generator.

Â We take its second value, which is 2.

Â Is i less than j, yes it does hold, so we're going to generate 1 + 2.

Â 8:45

Then, we're going to try the next value for j, which is 3.

Â Does this test hold?

Â Yes, it does.

Â We get 1 + 3 and I get the next value for j which is 4.

Â Does this hold? Yes, it does, we're going to get 1 + 4.

Â Now we exhausted all possible values for j.

Â We're going to have to go back to the next value for i which is 2.

Â So we try i is 2, j is 1, fails its test.

Â j is 2, also fails its test, j is 3, passes this test.

Â So we generate 2 + 3 and then we try j is 4, passes this test, we get 2 + 4.

Â 9:19

We've exhausted all the values for j, so we go back to the value for i.

Â Now we have the value for i is 3.

Â And we try j as 1, fails the test, j as 2, fails the test, j as 3, fails the test,

Â j as 4, passes the test.

Â So we can write 3 + 4, we've run out of ways for j,

Â we go back to i, and take it to 4.

Â Try all the ways for j and none of them pass this test, so we can write nothing.

Â We've run out of values for j.

Â We'll also run out of values for i, so we finish.

Â So all together these were the elements we generated.

Â These are basically pairs of i and j which passed this test.

Â But of course because it's a set comprehension, even though we have

Â two ways of getting 5 here, the set only has one copy of the value 5.

Â Let's have a look at an array comprehension, a more complicated one.

Â So we're building up this array of integers where we have taken i from

Â the set primes, and we've taken j in the valuation i minus 1 to 6.

Â And we're going to keep all the i, j pairs if you sum them up, you get an odd number.

Â So you think about how this works.

Â i takes its first value, 2, and j will take its first value,

Â which would be 1 and 1 to 6, so it would make 1.

Â Now 2 + 1 is odd, so we're going to generate this absolute value of 2- 1,

Â this expression here.

Â Now we'll try j is 2 but

Â this will fail this test because we sum them up we get an even number.

Â So then we'll take j is 3, we'll pass this test so we get this expression.

Â Then we'll take 4, we'll fail, 5 we'll succeed, getting this.

Â 6, we'll again fail the test and we'll finish all the values in j.

Â We'll go back to i and we'll take it to the next which is 3,

Â j will take variation 2 to 6.

Â We get 3- 2, 3- 4, and

Â the value of 3- 6 as the three cases where we pass this test.

Â And with these all j we go back to i, take them back from 5.

Â j's going to take values from 4 to 6 and we take the ones where that

Â adds up to an odd number which is 5 and 4, and 5 and 6.

Â Generate one copy of this expression for each of those and

Â we go back i takes the value 7 or you can take those j in rank 6 which is only 1.

Â It passes this test, so we get this one, then we go back and i takes a value of 11.

Â And then we're going to try j in the values 10 to 6, which is an empty range.

Â 11:49

There are no numbers in between 10 and 6, so

Â we're going to generate nothing, i is 13.

Â We're going to generate nothing.

Â Overall, these are all the expressions we're going to generate, and of course,

Â we're going to evaluate them all.

Â We get this array, right, and of course, this is not a set, so

Â the order of the array elements matters.

Â We can't move.

Â All right, let's look at another example of using arrays.

Â And here I've got a two-dimensional array which has five columns and two rows.

Â What is the result of this expression?

Â All right, I'm taking c of j, i,

Â there I'm iterating over the columns first, and then the rows.

Â And then I'm going to coerce it into a two-dimensional array with five rows and

Â two columns.

Â 12:38

So the first thing to think of is what does this expression here do?

Â Well, it says let's say i is 1 and j is 1 so we're going to get the first,

Â the top left most element in the array, 250.

Â Then it takes j is 2 which will be the first element in

Â the second row, which is 200.

Â Then it's finished j so it'll go back and

Â take i is 2 and j is 1, so we get 2 which is this bit,

Â which is this element, the second element in the first row.

Â And we'll get 0, 75, 150, 100, 150, 0, 75.

Â So the first thing is that this expression will generate this one-dimensional array,

Â which is basically a different order of the elements in c.

Â Then we're going to coerce that into an array with five rows and

Â two columns, so this is the array we generate.

Â And if you look at this array, with what we started off,

Â what we've actually generated is the transpose of c.

Â 13:44

So let's look at some more set and array comprehension examples.

Â So 3 * i + j, i takes the values from 2 to 3 and j is in prime.

Â So again, at each of these values here and add 4 to them and

Â add 6 to them, so, this is going to be the result, so

Â adding 4, adding 6, and adding 9.

Â If we add 6 to each of these numbers,

Â we're going to get 8, 9, 11, 13, 17 and 19.

Â And then we'll also add 9 to each of them.

Â So we get 11, 12, 14, 16, 20,

Â and 22, so the set will have all of those numbers in it.

Â 14:33

We're looking at i times j, we're looking at i taking values in the small set of

Â prime numbers and j taking values from 2 to i.

Â And then getting the i times j values where this j directly

Â completely divides i, the i mod j is 0.

Â We think about that, the only way, if I take the number 2,

Â the only number from 2 to 2 which divides it is 2 itself, so we get 4.

Â Take the number 3, the only number between 2 and

Â 3 which divide 3 exactly is the number 3, so we get 9.

Â Then because basically these numbers are prime, the only number that

Â divides them exactly is themselves or 1, but we're not working at.

Â So we're basically going to get all these.

Â All right, let's look at z.

Â So here we've got a set comprehension, inside an array comprehension.

Â So i is going to take the values in prime except where i is the value of 11, so

Â we're not going to use that.

Â 15:27

And for each of those sets, we're going to say, we're going to configurate

Â j with 1 to i, and take all the odd numbers from that value.

Â So in the first test, i is 2, all of the numbers in 2 is just 1.

Â And i is 3 we get 1 and 3, i is 5 we get 1, 3, and 5.

Â i is 7, we get 1, 3, 5, 7, i is 11 we don't do because we don't pass this test.

Â And for i is 13 we generate these set of odd numbers, so that's what.

Â 15:59

So MiniZinc provides a lot of built-in functions which operate over 1D arrays

Â because that's what we generate with these array comprehensions.

Â So we can have operations on lists of numbers like sum, product, min, and max,

Â and operations or lists of constraints like forall and exists.

Â And MiniZinc provides this special syntax.

Â If we write function in a generator, generator where bexpr,

Â you've got this where, that one.

Â And then the expression's just a shorthand for

Â saying do an array comprehension, and then apply this function on that array.

Â So running this is exactly the same with.

Â Like for example, if I write down for all i, j 1 to 10 where i is less than j,

Â a of i is not equivalent to a of j, it's the same as this.

Â I'm building an a of i not equal to a of j in my array for all here's i,

Â j in 1 to 10 where i is less than j.

Â And then I'm applying it for all in that array Boolean expressions.

Â 16:55

So let's look at some examples of generated call examples.

Â [COUGH] Let's take the sum i is in 2 to 3, j is in 3 to 4 of i + j.

Â Well, we're basically going to build this list of numbers, right?

Â 2 + 3 and 2 + 4 and 3 + 3 and 3 + 4 is 5, 6, and 7.

Â And sum them up, we're going to get x 24.

Â Now here's almost exactly the same thing, except now I'm

Â basically summing up a set comprehension of exactly the same thing.

Â What happens now?

Â Well, I actually build up the set, right?

Â I take 5, 6, 6, and 7 into my set, but the set is 5, 6, and 7.

Â I take their sum, and get the value 18.

Â Now with this sum taking numbers i and PRIME and j in 2 to 3, and

Â looking at i times j mod 30.

Â Well, it's going to generate all the multiples of 2 of these things and

Â all the multiples of 3 of these things and take mod 30 of each of them.

Â And then find the minimum one, and in fact, it would turn out to be when y is 3,

Â which is minimum happens when i is 11 and j is 3.

Â 18:07

So again, with a value of 3.

Â We look at this one, we take all the values i in PRIME and j in 2...i-1,

Â and we want to find cases does there exist a case where j divides i exactly.

Â So i mod j equals zero, and

Â of course there is a prime number that only divides it is i and itself.

Â So all of these things are very likely false.

Â Exists over all things which are false, will give us this number.

Â 18:37

So MiniZinc uses sets to name sets of objects.

Â So this allows us to talk about the collection of objects and do

Â things on the whole collection, and arrays capture information about those objects.

Â And then, with that, we can build comprehensions to build constraints and

Â expressions over these sets of objects of differently-sized data.

Â You're going to need to learn how to use comprehensions to build the data and

Â constraints and model complex problems.

Â And you can see more of that comprehensions in, for example,

Â in this Wikipedia file.

Â That brings us to the end of this section.

Â