DotNet Reference

.Net Reference

ConstraintSolverTests.cs
Go to the documentation of this file.
1 // Copyright 2010-2022 Google LLC
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 using System;
15 using Xunit;
17 using static Google.OrTools.ConstraintSolver.operations_research_constraint_solver;
18 
19 namespace Google.OrTools.Tests
20 {
22 {
23  [Fact]
24  public void IntVectorToInt64Vector()
25  {
26  int[] input = { 5, 11, 17 };
27  long[] output = ToInt64Vector(input);
28  Assert.Equal(3, output.Length);
29  Assert.Equal(5, output[0]);
30  Assert.Equal(11, output[1]);
31  Assert.Equal(17, output[2]);
32  }
33 
34  [Fact]
35  public void IntVarConstructor()
36  {
37  Solver solver = new Solver("Solver");
38  Assert.NotNull(solver);
39  IntVar x = solver.MakeIntVar(3, 7, "x");
40  Assert.Equal(3, x.Min());
41  Assert.Equal(7, x.Max());
42  Assert.Equal("x(3..7)", x.ToString());
43  }
44 
45  [Fact]
46  public void ConstraintConstructor()
47  {
48  Solver solver = new Solver("Solver");
49  Assert.NotNull(solver);
50  IntVar x = solver.MakeIntVar(3, 7, "x");
51  Assert.Equal("x(3..7)", x.ToString());
52 
53  // Unary operator
54  Constraint c0 = (x == 5);
55  Assert.Equal("(x(3..7) == 5)", c0.ToString());
56  IntExpr e1 = -c0;
57  Assert.Equal("-(Watch<x == 5>(0 .. 1))", e1.ToString());
58  IntExpr e2 = c0.Abs();
59  Assert.Equal("Watch<x == 5>(0 .. 1)", e2.ToString());
60  IntExpr e3 = c0.Square();
61  Assert.Equal("IntSquare(Watch<x == 5>(0 .. 1))", e3.ToString());
62 
63  // Relational operator with a scalar
64  Constraint c1 = x == 5;
65  Assert.Equal("(x(3..7) == 5)", c1.ToString());
66  Constraint c2 = x >= 5;
67  Assert.Equal("(x(3..7) >= 5)", c2.ToString());
68  Constraint c3 = x > 5;
69  Assert.Equal("(x(3..7) >= 6)", c3.ToString());
70  Constraint c4 = x <= 5;
71  Assert.Equal("(x(3..7) <= 5)", c4.ToString());
72  Constraint c5 = x < 5;
73  Assert.Equal("(x(3..7) <= 4)", c5.ToString());
74  Constraint c6 = x != 5;
75  Assert.Equal("(x(3..7) != 5)", c6.ToString());
76  Constraint c7 = x == 2;
77  Assert.Equal("FalseConstraint()", c7.ToString());
78  }
79 
80  [Fact]
81  public void IntExprConstructor()
82  {
83  Solver solver = new Solver("Solver");
84  Assert.NotNull(solver);
85  IntVar x = solver.MakeIntVar(3, 13, "x");
86  Assert.Equal(3, x.Min());
87  Assert.Equal(13, x.Max());
88 
89  // Unary Operator
90  IntExpr e1 = -(x == 7);
91  Assert.Equal("-(Watch<x == 7>(0 .. 1))", e1.ToString());
92  IntExpr e2 = (x == 7).Abs();
93  Assert.Equal("Watch<x == 7>(0 .. 1)", e2.ToString());
94  IntExpr e3 = (x == 7).Square();
95  Assert.Equal("IntSquare(Watch<x == 7>(0 .. 1))", e3.ToString());
96  }
97 
98  [Fact]
100  {
101  Solver solver = new Solver("Solver");
102  Assert.NotNull(solver);
103  IntVar x = solver.MakeIntVar(3, 13, "x");
104  Assert.Equal(3, x.Min());
105  Assert.Equal(13, x.Max());
106 
107  // Unary Operator
108  IntExpr e1 = -(x >= 7);
109  Assert.Equal("-(Watch<x >= 7>(0 .. 1))", e1.ToString());
110  IntExpr e2 = (x >= 7).Abs();
111  Assert.Equal("Watch<x >= 7>(0 .. 1)", e2.ToString());
112  IntExpr e3 = (x >= 7).Square();
113  Assert.Equal("IntSquare(Watch<x >= 7>(0 .. 1))", e3.ToString());
114  }
115 
116  [Fact]
117  public void ConstraintAndScalar()
118  {
119  Solver solver = new Solver("Solver");
120  Assert.NotNull(solver);
121  IntVar x = solver.MakeIntVar(3, 13, "x");
122  Assert.Equal(3, x.Min());
123  Assert.Equal(13, x.Max());
124 
125  Constraint c1 = (x == 7);
126  Assert.Equal("(x(3..13) == 7)", c1.ToString());
127 
128  // Arithmetic operator with a scalar
129  IntExpr e2a = c1 + 1;
130  Assert.Equal("(Watch<x == 7>(0 .. 1) + 1)", e2a.ToString());
131  IntExpr e2b = 1 + c1;
132  Assert.Equal("(Watch<x == 7>(0 .. 1) + 1)", e2b.ToString());
133 
134  IntExpr e2c = c1 - 1;
135  Assert.Equal("(Watch<x == 7>(0 .. 1) + -1)", e2c.ToString());
136  IntExpr e2d = 1 - c1;
137  Assert.Equal("Not(Watch<x == 7>(0 .. 1))", e2d.ToString());
138 
139  IntExpr e2e = c1 * 2;
140  Assert.Equal("(Watch<x == 7>(0 .. 1) * 2)", e2e.ToString());
141  IntExpr e2f = 2 * c1;
142  Assert.Equal("(Watch<x == 7>(0 .. 1) * 2)", e2f.ToString());
143 
144  IntExpr e2g = c1 / 4;
145  Assert.Equal("(Watch<x == 7>(0 .. 1) div 4)", e2g.ToString());
146 
147  // Relational operator with a scalar
148  Constraint c8a = c1 == 1;
149  Assert.Equal("(Watch<x == 7>(0 .. 1) == 1)", c8a.ToString());
150  Constraint c8b = 1 == c1;
151  Assert.Equal("(Watch<x == 7>(0 .. 1) == 1)", c8b.ToString());
152 
153  Constraint c8c = c1 != 1;
154  Assert.Equal("(Watch<x == 7>(0 .. 1) != 1)", c8c.ToString());
155  Constraint c8d = 1 != c1;
156  Assert.Equal("(Watch<x == 7>(0 .. 1) != 1)", c8d.ToString());
157 
158  Constraint c8e = c1 >= 1;
159  Assert.Equal("(Watch<x == 7>(0 .. 1) >= 1)", c8e.ToString());
160  Constraint c8f = 1 >= c1;
161  Assert.Equal("TrueConstraint()", c8f.ToString());
162 
163  Constraint c8g = c1 > 1;
164  Assert.Equal("FalseConstraint()", c8g.ToString());
165  Constraint c8h = 1 > c1;
166  Assert.Equal("(Watch<x == 7>(0 .. 1) <= 0)", c8h.ToString());
167 
168  Constraint c8i = c1 <= 1;
169  Assert.Equal("TrueConstraint()", c8i.ToString());
170  Constraint c8j = 1 <= c1;
171  Assert.Equal("(Watch<x == 7>(0 .. 1) >= 1)", c8j.ToString());
172 
173  Constraint c8k = c1 < 1;
174  Assert.Equal("(Watch<x == 7>(0 .. 1) <= 0)", c8k.ToString());
175  Constraint c8l = 1 < c1;
176  Assert.Equal("FalseConstraint()", c8l.ToString());
177  }
178 
179  [Fact]
180  public void ConstraintAndIntVar()
181  {
182  Solver solver = new Solver("Solver");
183  Assert.NotNull(solver);
184  IntVar x = solver.MakeIntVar(3, 13, "x");
185  Assert.Equal(3, x.Min());
186  Assert.Equal(13, x.Max());
187 
188  Constraint c1 = x == 7;
189  Assert.Equal("(x(3..13) == 7)", c1.ToString());
190 
191  IntVar y = solver.MakeIntVar(5, 17, "y");
192  Assert.Equal(5, y.Min());
193  Assert.Equal(17, y.Max());
194 
195  // Arithmetic operator with IntVar
196  IntExpr e3a = c1 + y;
197  Assert.Equal("(Watch<x == 7>(0 .. 1) + y(5..17))", e3a.ToString());
198  IntExpr e3b = y + c1;
199  Assert.Equal("(Watch<x == 7>(0 .. 1) + y(5..17))", e3b.ToString());
200 
201  IntExpr e3c = c1 - y;
202  Assert.Equal("(Watch<x == 7>(0 .. 1) - y(5..17))", e3c.ToString());
203  IntExpr e3d = y - c1;
204  Assert.Equal("(y(5..17) - Watch<x == 7>(0 .. 1))", e3d.ToString());
205 
206  IntExpr e3e = c1 * y;
207  Assert.Equal("(Watch<x == 7>(0 .. 1) * y(5..17))", e3e.ToString());
208  IntExpr e3f = y * c1;
209  Assert.Equal("(Watch<x == 7>(0 .. 1) * y(5..17))", e3f.ToString());
210 
211  // Relational operator with an IntVar
212  Constraint c9a = c1 == y;
213  Assert.Equal("Watch<x == 7>(0 .. 1) == y(5..17)", c9a.ToString());
214  Constraint c9b = y == c1;
215  Assert.Equal("y(5..17) == Watch<x == 7>(0 .. 1)", c9b.ToString());
216 
217  Constraint c9c = c1 != y;
218  Assert.Equal("Watch<x == 7>(0 .. 1) != y(5..17)", c9c.ToString());
219  Constraint c9d = y != c1;
220  Assert.Equal("y(5..17) != Watch<x == 7>(0 .. 1)", c9d.ToString());
221 
222  Constraint c9e = c1 >= y;
223  Assert.Equal("y(5..17) <= Watch<x == 7>(0 .. 1)", c9e.ToString());
224  Constraint c9f = y >= c1;
225  Assert.Equal("Watch<x == 7>(0 .. 1) <= y(5..17)", c9f.ToString());
226 
227  Constraint c9g = c1 > y;
228  Assert.Equal("y(5..17) < Watch<x == 7>(0 .. 1)", c9g.ToString());
229  Constraint c9h = y > c1;
230  Assert.Equal("Watch<x == 7>(0 .. 1) < y(5..17)", c9h.ToString());
231 
232  Constraint c9i = c1 <= y;
233  Assert.Equal("Watch<x == 7>(0 .. 1) <= y(5..17)", c9i.ToString());
234  Constraint c9j = y <= c1;
235  Assert.Equal("y(5..17) <= Watch<x == 7>(0 .. 1)", c9j.ToString());
236 
237  Constraint c9k = c1 < y;
238  Assert.Equal("Watch<x == 7>(0 .. 1) < y(5..17)", c9k.ToString());
239  Constraint c9l = y < c1;
240  Assert.Equal("y(5..17) < Watch<x == 7>(0 .. 1)", c9l.ToString());
241  }
242 
243  [Fact]
244  public void ConstraintAndIntExpr()
245  {
246  Solver solver = new Solver("Solver");
247  Assert.NotNull(solver);
248  IntVar x = solver.MakeIntVar(3, 13, "x");
249  Assert.Equal(3, x.Min());
250  Assert.Equal(13, x.Max());
251  Constraint c1 = x == 7;
252  Assert.Equal("(x(3..13) == 7)", c1.ToString());
253 
254  IntVar y = solver.MakeIntVar(5, 17, "y");
255  Assert.Equal(5, y.Min());
256  Assert.Equal(17, y.Max());
257 
258  // Arithmetic operator with an IntExpr
259  IntExpr e11a = c1 + (y == 11);
260  Assert.Equal("(Watch<x == 7>(0 .. 1) + Watch<y == 11>(0 .. 1))", e11a.ToString());
261  IntExpr e11b = (y == 11) + c1;
262  Assert.Equal("(Watch<x == 7>(0 .. 1) + Watch<y == 11>(0 .. 1))", e11b.ToString());
263  IntExpr e11c = c1 - (y == 11);
264  Assert.Equal("(Watch<x == 7>(0 .. 1) - Watch<y == 11>(0 .. 1))", e11c.ToString());
265  IntExpr e11d = (y == 11) - c1;
266  Assert.Equal("(Watch<y == 11>(0 .. 1) - Watch<x == 7>(0 .. 1))", e11d.ToString());
267  IntExpr e11e = c1 * (y == 11);
268  Assert.Equal("(Watch<x == 7>(0 .. 1) * Watch<y == 11>(0 .. 1))", e11e.ToString());
269  IntExpr e11f = (y == 11) * c1;
270  Assert.Equal("(Watch<x == 7>(0 .. 1) * Watch<y == 11>(0 .. 1))", e11f.ToString());
271 
272  // Relational operator with an IntExpr
273  Constraint c12a = c1 == (y == 11);
274  Assert.Equal("Watch<x == 7>(0 .. 1) == Watch<y == 11>(0 .. 1)", c12a.ToString());
275  Constraint c12b = (y == 11) == c1;
276  Assert.Equal("Watch<y == 11>(0 .. 1) == Watch<x == 7>(0 .. 1)", c12b.ToString());
277  Constraint c12c = c1 != (y == 11);
278  Assert.Equal("Watch<x == 7>(0 .. 1) != Watch<y == 11>(0 .. 1)", c12c.ToString());
279  Constraint c12d = (y == 11) != c1;
280  Assert.Equal("Watch<y == 11>(0 .. 1) != Watch<x == 7>(0 .. 1)", c12d.ToString());
281  Constraint c12e = c1 >= (y == 11);
282  Assert.Equal("Watch<y == 11>(0 .. 1) <= Watch<x == 7>(0 .. 1)", c12e.ToString());
283  Constraint c12f = (y == 11) >= c1;
284  Assert.Equal("Watch<x == 7>(0 .. 1) <= Watch<y == 11>(0 .. 1)", c12f.ToString());
285  Constraint c12g = c1 > (y == 11);
286  Assert.Equal("Watch<y == 11>(0 .. 1) < Watch<x == 7>(0 .. 1)", c12g.ToString());
287  Constraint c12h = (y == 11) > c1;
288  Assert.Equal("Watch<x == 7>(0 .. 1) < Watch<y == 11>(0 .. 1)", c12h.ToString());
289  Constraint c12i = c1 <= (y == 11);
290  Assert.Equal("Watch<x == 7>(0 .. 1) <= Watch<y == 11>(0 .. 1)", c12i.ToString());
291  Constraint c12j = (y == 11) <= c1;
292  Assert.Equal("Watch<y == 11>(0 .. 1) <= Watch<x == 7>(0 .. 1)", c12j.ToString());
293  Constraint c12k = c1 < (y == 11);
294  Assert.Equal("Watch<x == 7>(0 .. 1) < Watch<y == 11>(0 .. 1)", c12k.ToString());
295  Constraint c12l = (y == 11) < c1;
296  Assert.Equal("Watch<y == 11>(0 .. 1) < Watch<x == 7>(0 .. 1)", c12l.ToString());
297  }
298 
299  [Fact]
301  {
302  Solver solver = new Solver("Solver");
303  Assert.NotNull(solver);
304  IntVar x = solver.MakeIntVar(3, 13, "x");
305  Assert.Equal(3, x.Min());
306  Assert.Equal(13, x.Max());
307  Constraint c1 = x == 7;
308  Assert.Equal("(x(3..13) == 7)", c1.ToString());
309 
310  IntVar y = solver.MakeIntVar(5, 17, "y");
311  Assert.Equal(5, y.Min());
312  Assert.Equal(17, y.Max());
313  Constraint c2 = y == 11;
314  Assert.Equal("(y(5..17) == 11)", c2.ToString());
315 
316  // Relational operator with a Constraint
317  Constraint c10a = c1 == c2;
318  Assert.Equal("Watch<x == 7>(0 .. 1) == Watch<y == 11>(0 .. 1)", c10a.ToString());
319 
320  Constraint c10b = c1 != c2;
321  Assert.Equal("Watch<x == 7>(0 .. 1) != Watch<y == 11>(0 .. 1)", c10b.ToString());
322 
323  Constraint c10c = c1 <= c2;
324  Assert.Equal("Watch<x == 7>(0 .. 1) <= Watch<y == 11>(0 .. 1)", c10c.ToString());
325  Constraint c10d = c1 >= c2;
326  Assert.Equal("Watch<y == 11>(0 .. 1) <= Watch<x == 7>(0 .. 1)", c10d.ToString());
327 
328  Constraint c10e = c1 > c2;
329  Assert.Equal("Watch<y == 11>(0 .. 1) < Watch<x == 7>(0 .. 1)", c10e.ToString());
330  Constraint c10f = c1 < c2;
331  Assert.Equal("Watch<x == 7>(0 .. 1) < Watch<y == 11>(0 .. 1)", c10f.ToString());
332  }
333 
334  [Fact]
335  public void IntExprAndScalar()
336  {
337  Solver solver = new Solver("Solver");
338  Assert.NotNull(solver);
339  IntVar x = solver.MakeIntVar(3, 13, "x");
340  Assert.Equal(3, x.Min());
341  Assert.Equal(13, x.Max());
342 
343  // Arithmetic operator with a scalar
344  IntExpr e2a = (x == 7) + 1;
345  Assert.Equal("(Watch<x == 7>(0 .. 1) + 1)", e2a.ToString());
346  IntExpr e2b = 1 + (x == 7);
347  Assert.Equal("(Watch<x == 7>(0 .. 1) + 1)", e2b.ToString());
348 
349  IntExpr e2c = (x == 7) - 1;
350  Assert.Equal("(Watch<x == 7>(0 .. 1) + -1)", e2c.ToString());
351  IntExpr e2d = 1 - (x == 7);
352  Assert.Equal("Not(Watch<x == 7>(0 .. 1))", e2d.ToString());
353 
354  IntExpr e2e = (x == 7) * 2;
355  Assert.Equal("(Watch<x == 7>(0 .. 1) * 2)", e2e.ToString());
356  IntExpr e2f = 2 * (x == 7);
357  Assert.Equal("(Watch<x == 7>(0 .. 1) * 2)", e2f.ToString());
358 
359  IntExpr e2g = (x == 7) / 4;
360  Assert.Equal("(Watch<x == 7>(0 .. 1) div 4)", e2g.ToString());
361 
362  // Relational operator with a scalar
363  Constraint c8a = (x == 7) == 1;
364  Assert.Equal("(Watch<x == 7>(0 .. 1) == 1)", c8a.ToString());
365  Constraint c8b = 1 == (x == 7);
366  Assert.Equal("(Watch<x == 7>(0 .. 1) == 1)", c8b.ToString());
367 
368  Constraint c8c = (x == 7) != 1;
369  Assert.Equal("(Watch<x == 7>(0 .. 1) != 1)", c8c.ToString());
370  Constraint c8d = 1 != (x == 7);
371  Assert.Equal("(Watch<x == 7>(0 .. 1) != 1)", c8d.ToString());
372 
373  Constraint c8e = (x == 7) >= 1;
374  Assert.Equal("(Watch<x == 7>(0 .. 1) >= 1)", c8e.ToString());
375  Constraint c8f = 1 >= (x == 7);
376  Assert.Equal("TrueConstraint()", c8f.ToString());
377 
378  Constraint c8g = (x == 7) > 1;
379  Assert.Equal("FalseConstraint()", c8g.ToString());
380  Constraint c8h = 1 > (x == 7);
381  Assert.Equal("(Watch<x == 7>(0 .. 1) <= 0)", c8h.ToString());
382 
383  Constraint c8i = (x == 7) <= 1;
384  Assert.Equal("TrueConstraint()", c8i.ToString());
385  Constraint c8j = 1 <= (x == 7);
386  Assert.Equal("(Watch<x == 7>(0 .. 1) >= 1)", c8j.ToString());
387 
388  Constraint c8k = (x == 7) < 1;
389  Assert.Equal("(Watch<x == 7>(0 .. 1) <= 0)", c8k.ToString());
390  Constraint c8l = 1 < (x == 7);
391  Assert.Equal("FalseConstraint()", c8l.ToString());
392  }
393 
394  [Fact]
395  public void IntExprAndIntVar()
396  {
397  Solver solver = new Solver("Solver");
398  Assert.NotNull(solver);
399  IntVar x = solver.MakeIntVar(3, 13, "x");
400  Assert.Equal(3, x.Min());
401  Assert.Equal(13, x.Max());
402 
403  IntVar y = solver.MakeIntVar(5, 17, "y");
404  Assert.Equal(5, y.Min());
405  Assert.Equal(17, y.Max());
406 
407  // Arithmetic operator with IntVar
408  IntExpr e3a = (x == 7) + y;
409  Assert.Equal("(Watch<x == 7>(0 .. 1) + y(5..17))", e3a.ToString());
410  IntExpr e3b = y + (x == 7);
411  Assert.Equal("(Watch<x == 7>(0 .. 1) + y(5..17))", e3b.ToString());
412 
413  IntExpr e3c = (x == 7) - y;
414  Assert.Equal("(Watch<x == 7>(0 .. 1) - y(5..17))", e3c.ToString());
415  IntExpr e3d = y - (x == 7);
416  Assert.Equal("(y(5..17) - Watch<x == 7>(0 .. 1))", e3d.ToString());
417 
418  IntExpr e3e = (x == 7) * y;
419  Assert.Equal("(Watch<x == 7>(0 .. 1) * y(5..17))", e3e.ToString());
420  IntExpr e3f = y * (x == 7);
421  Assert.Equal("(Watch<x == 7>(0 .. 1) * y(5..17))", e3f.ToString());
422 
423  // Relational operator with an IntVar
424  Constraint c9a = (x == 7) == y;
425  Assert.Equal("Watch<x == 7>(0 .. 1) == y(5..17)", c9a.ToString());
426  Constraint c9b = y == (x == 7);
427  Assert.Equal("y(5..17) == Watch<x == 7>(0 .. 1)", c9b.ToString());
428 
429  Constraint c9c = (x == 7) != y;
430  Assert.Equal("Watch<x == 7>(0 .. 1) != y(5..17)", c9c.ToString());
431  Constraint c9d = y != (x == 7);
432  Assert.Equal("y(5..17) != Watch<x == 7>(0 .. 1)", c9d.ToString());
433 
434  Constraint c9e = (x == 7) >= y;
435  Assert.Equal("y(5..17) <= Watch<x == 7>(0 .. 1)", c9e.ToString());
436  Constraint c9f = y >= (x == 7);
437  Assert.Equal("Watch<x == 7>(0 .. 1) <= y(5..17)", c9f.ToString());
438 
439  Constraint c9g = (x == 7) > y;
440  Assert.Equal("y(5..17) < Watch<x == 7>(0 .. 1)", c9g.ToString());
441  Constraint c9h = y > (x == 7);
442  Assert.Equal("Watch<x == 7>(0 .. 1) < y(5..17)", c9h.ToString());
443 
444  Constraint c9i = (x == 7) <= y;
445  Assert.Equal("Watch<x == 7>(0 .. 1) <= y(5..17)", c9i.ToString());
446  Constraint c9j = y <= (x == 7);
447  Assert.Equal("y(5..17) <= Watch<x == 7>(0 .. 1)", c9j.ToString());
448 
449  Constraint c9k = (x == 7) < y;
450  Assert.Equal("Watch<x == 7>(0 .. 1) < y(5..17)", c9k.ToString());
451  Constraint c9l = y < (x == 7);
452  Assert.Equal("y(5..17) < Watch<x == 7>(0 .. 1)", c9l.ToString());
453  }
454 
455  [Fact]
456  public void IntExprAndIntExpr()
457  {
458  Solver solver = new Solver("Solver");
459  Assert.NotNull(solver);
460  IntVar x = solver.MakeIntVar(3, 13, "x");
461  Assert.Equal(3, x.Min());
462  Assert.Equal(13, x.Max());
463 
464  IntVar y = solver.MakeIntVar(5, 17, "y");
465  Assert.Equal(5, y.Min());
466  Assert.Equal(17, y.Max());
467 
468  // Relational operator between IntExpr
469  Constraint c10a = (x == 7) == (y == 11);
470  Assert.Equal("Watch<x == 7>(0 .. 1) == Watch<y == 11>(0 .. 1)", c10a.ToString());
471 
472  Constraint c10b = (x == 7) != (y == 11);
473  Assert.Equal("Watch<x == 7>(0 .. 1) != Watch<y == 11>(0 .. 1)", c10b.ToString());
474 
475  Constraint c10c = (x == 7) <= (y == 11);
476  Assert.Equal("Watch<x == 7>(0 .. 1) <= Watch<y == 11>(0 .. 1)", c10c.ToString());
477  Constraint c10d = (x == 7) >= (y == 11);
478  Assert.Equal("Watch<y == 11>(0 .. 1) <= Watch<x == 7>(0 .. 1)", c10d.ToString());
479 
480  Constraint c10e = (x == 7) > (y == 11);
481  Assert.Equal("Watch<y == 11>(0 .. 1) < Watch<x == 7>(0 .. 1)", c10e.ToString());
482  Constraint c10f = (x == 7) < (y == 11);
483  Assert.Equal("Watch<x == 7>(0 .. 1) < Watch<y == 11>(0 .. 1)", c10f.ToString());
484  }
485 
486  [Fact]
488  {
489  Solver solver = new Solver("Solver");
490  Assert.NotNull(solver);
491  IntVar x = solver.MakeIntVar(3, 13, "x");
492  Assert.Equal(3, x.Min());
493  Assert.Equal(13, x.Max());
494 
495  // Arithmetic operator with a scalar
496  IntExpr e2a = (x >= 7) + 1;
497  Assert.Equal("(Watch<x >= 7>(0 .. 1) + 1)", e2a.ToString());
498  IntExpr e2b = 1 + (x >= 7);
499  Assert.Equal("(Watch<x >= 7>(0 .. 1) + 1)", e2b.ToString());
500 
501  IntExpr e2c = (x >= 7) - 1;
502  Assert.Equal("(Watch<x >= 7>(0 .. 1) + -1)", e2c.ToString());
503  IntExpr e2d = 1 - (x >= 7);
504  Assert.Equal("Not(Watch<x >= 7>(0 .. 1))", e2d.ToString());
505 
506  IntExpr e2e = (x >= 7) * 2;
507  Assert.Equal("(Watch<x >= 7>(0 .. 1) * 2)", e2e.ToString());
508  IntExpr e2f = 2 * (x >= 7);
509  Assert.Equal("(Watch<x >= 7>(0 .. 1) * 2)", e2f.ToString());
510 
511  // Relational operator with a scalar
512  Constraint c8a = (x >= 7) == 1;
513  Assert.Equal("(Watch<x >= 7>(0 .. 1) == 1)", c8a.ToString());
514  Constraint c8b = 1 == (x >= 7);
515  Assert.Equal("(Watch<x >= 7>(0 .. 1) == 1)", c8b.ToString());
516 
517  Constraint c8c = (x >= 7) != 1;
518  Assert.Equal("(Watch<x >= 7>(0 .. 1) != 1)", c8c.ToString());
519  Constraint c8d = 1 != (x >= 7);
520  Assert.Equal("(Watch<x >= 7>(0 .. 1) != 1)", c8d.ToString());
521 
522  Constraint c8e = (x >= 7) >= 1;
523  Assert.Equal("(Watch<x >= 7>(0 .. 1) >= 1)", c8e.ToString());
524  Constraint c8f = 1 >= (x >= 7);
525  Assert.Equal("TrueConstraint()", c8f.ToString());
526 
527  Constraint c8g = (x >= 7) > 1;
528  Assert.Equal("FalseConstraint()", c8g.ToString());
529  Constraint c8h = 1 > (x >= 7);
530  Assert.Equal("(Watch<x >= 7>(0 .. 1) <= 0)", c8h.ToString());
531 
532  Constraint c8i = (x >= 7) <= 1;
533  Assert.Equal("TrueConstraint()", c8i.ToString());
534  Constraint c8j = 1 <= (x >= 7);
535  Assert.Equal("(Watch<x >= 7>(0 .. 1) >= 1)", c8j.ToString());
536 
537  Constraint c8k = (x >= 7) < 1;
538  Assert.Equal("(Watch<x >= 7>(0 .. 1) <= 0)", c8k.ToString());
539  Constraint c8l = 1 < (x >= 7);
540  Assert.Equal("FalseConstraint()", c8l.ToString());
541  }
542 
543  [Fact]
545  {
546  Solver solver = new Solver("Solver");
547  Assert.NotNull(solver);
548  IntVar x = solver.MakeIntVar(3, 13, "x");
549  Assert.Equal(3, x.Min());
550  Assert.Equal(13, x.Max());
551 
552  IntVar y = solver.MakeIntVar(5, 17, "y");
553  Assert.Equal(5, y.Min());
554  Assert.Equal(17, y.Max());
555 
556  // Arithmetic operator with IntVar
557  IntExpr e3a = (x >= 7) + y;
558  Assert.Equal("(Watch<x >= 7>(0 .. 1) + y(5..17))", e3a.ToString());
559  IntExpr e3b = y + (x >= 7);
560  Assert.Equal("(Watch<x >= 7>(0 .. 1) + y(5..17))", e3b.ToString());
561 
562  IntExpr e3c = (x >= 7) - y;
563  Assert.Equal("(Watch<x >= 7>(0 .. 1) - y(5..17))", e3c.ToString());
564  IntExpr e3d = y - (x >= 7);
565  Assert.Equal("(y(5..17) - Watch<x >= 7>(0 .. 1))", e3d.ToString());
566 
567  IntExpr e3e = (x >= 7) * y;
568  Assert.Equal("(Watch<x >= 7>(0 .. 1) * y(5..17))", e3e.ToString());
569  IntExpr e3f = y * (x >= 7);
570  Assert.Equal("(Watch<x >= 7>(0 .. 1) * y(5..17))", e3f.ToString());
571 
572  // Relational operator with an IntVar
573  Constraint c9a = (x >= 7) == y;
574  Assert.Equal("Watch<x >= 7>(0 .. 1) == y(5..17)", c9a.ToString());
575  Constraint c9b = y == (x >= 7);
576  Assert.Equal("y(5..17) == Watch<x >= 7>(0 .. 1)", c9b.ToString());
577 
578  Constraint c9c = (x >= 7) != y;
579  Assert.Equal("Watch<x >= 7>(0 .. 1) != y(5..17)", c9c.ToString());
580  Constraint c9d = y != (x >= 7);
581  Assert.Equal("y(5..17) != Watch<x >= 7>(0 .. 1)", c9d.ToString());
582 
583  Constraint c9e = (x >= 7) >= y;
584  Assert.Equal("y(5..17) <= Watch<x >= 7>(0 .. 1)", c9e.ToString());
585  Constraint c9f = y >= (x >= 7);
586  Assert.Equal("Watch<x >= 7>(0 .. 1) <= y(5..17)", c9f.ToString());
587 
588  Constraint c9g = (x >= 7) > y;
589  Assert.Equal("y(5..17) < Watch<x >= 7>(0 .. 1)", c9g.ToString());
590  Constraint c9h = y > (x >= 7);
591  Assert.Equal("Watch<x >= 7>(0 .. 1) < y(5..17)", c9h.ToString());
592 
593  Constraint c9i = (x >= 7) <= y;
594  Assert.Equal("Watch<x >= 7>(0 .. 1) <= y(5..17)", c9i.ToString());
595  Constraint c9j = y <= (x >= 7);
596  Assert.Equal("y(5..17) <= Watch<x >= 7>(0 .. 1)", c9j.ToString());
597 
598  Constraint c9k = (x >= 7) < y;
599  Assert.Equal("Watch<x >= 7>(0 .. 1) < y(5..17)", c9k.ToString());
600  Constraint c9l = y < (x >= 7);
601  Assert.Equal("y(5..17) < Watch<x >= 7>(0 .. 1)", c9l.ToString());
602  }
603 
604  [Fact]
606  {
607  Solver solver = new Solver("Solver");
608  Assert.NotNull(solver);
609  IntVar x = solver.MakeIntVar(3, 13, "x");
610  Assert.Equal(3, x.Min());
611  Assert.Equal(13, x.Max());
612 
613  IntVar y = solver.MakeIntVar(5, 17, "y");
614  Assert.Equal(5, y.Min());
615  Assert.Equal(17, y.Max());
616 
617  // Relational operator between IntExpr
618  Constraint c10a = (x >= 7) == (y >= 11);
619  Assert.Equal("Watch<x >= 7>(0 .. 1) == Watch<y >= 11>(0 .. 1)", c10a.ToString());
620 
621  Constraint c10b = (x >= 7) != (y >= 11);
622  Assert.Equal("Watch<x >= 7>(0 .. 1) != Watch<y >= 11>(0 .. 1)", c10b.ToString());
623 
624  Constraint c10c = (x >= 7) <= (y >= 11);
625  Assert.Equal("Watch<x >= 7>(0 .. 1) <= Watch<y >= 11>(0 .. 1)", c10c.ToString());
626  Constraint c10d = (x >= 7) >= (y >= 11);
627  Assert.Equal("Watch<y >= 11>(0 .. 1) <= Watch<x >= 7>(0 .. 1)", c10d.ToString());
628 
629  Constraint c10e = (x >= 7) > (y >= 11);
630  Assert.Equal("Watch<y >= 11>(0 .. 1) < Watch<x >= 7>(0 .. 1)", c10e.ToString());
631  Constraint c10f = (x >= 7) < (y >= 11);
632  Assert.Equal("Watch<x >= 7>(0 .. 1) < Watch<y >= 11>(0 .. 1)", c10f.ToString());
633  }
634 
635  [Fact]
636  public void Downcast()
637  {
638  Solver solver = new Solver("Solver");
639  Assert.NotNull(solver);
640  IntVar x = solver.MakeIntVar(2, 17, "x");
641  IntExpr e = x + 5;
642  IntVar y = e.Var();
643  Assert.Equal("(x(2..17) + 5)", y.ToString());
644  }
645 
646  [Fact]
647  public void Sequence()
648  {
649  Solver solver = new Solver("Solver");
650  Assert.NotNull(solver);
651  IntervalVar[] intervals = solver.MakeFixedDurationIntervalVarArray(10, 0, 10, 5, false, "task");
652  DisjunctiveConstraint disjunctive = intervals.Disjunctive("Sequence");
653  SequenceVar var = disjunctive.SequenceVar();
654  Assignment ass = solver.MakeAssignment();
655  ass.Add(var);
656  ass.SetForwardSequence(var, new int[] { 1, 3, 5 });
657  int[] seq = ass.ForwardSequence(var);
658  Assert.Equal(3, seq.Length);
659  Assert.Equal(1, seq[0]);
660  Assert.Equal(3, seq[1]);
661  Assert.Equal(5, seq[2]);
662  }
663 
664  // A simple demon that simply sets the maximum of a fixed IntVar to 10 when
665  // it's being called.
666  class SetMaxDemon : NetDemon
667  {
668  public SetMaxDemon(IntVar x)
669  {
670  x_ = x;
671  }
672  public override void Run(Solver s)
673  {
674  x_.SetMax(10);
675  }
676  private IntVar x_;
677  }
678 
679  [Fact]
680  public void Demon()
681  {
682  Solver solver = new Solver("DemonTest");
683  Assert.NotNull(solver);
684  IntVar x = solver.MakeIntVar(new int[] { 2, 4, -1, 6, 11, 10 }, "x");
685  NetDemon demon = new SetMaxDemon(x);
686  Assert.Equal(11, x.Max());
687  demon.Run(solver);
688  Assert.Equal(10, x.Max());
689  }
690 
691  // This constraint has a single target variable x. It enforces x >= 5 upon
692  // InitialPropagate() and invokes the SetMaxDemon when x changes its range.
693  class SetMinAndMaxConstraint : NetConstraint
694  {
695  public SetMinAndMaxConstraint(Solver solver, IntVar x) : base(solver)
696  {
697  x_ = x;
698  }
699  public override void Post()
700  {
701  // Always store the demon in the constraint to avoid it being reclaimed
702  // by the GC.
703  demon_ = new SetMaxDemon(x_);
704  x_.WhenBound(demon_);
705  }
706  public override void InitialPropagate()
707  {
708  x_.SetMin(5);
709  }
710  private IntVar x_;
711  private Demon demon_;
712  }
713 
714  [Fact]
715  public void MinAndMaxConstraint()
716  {
717  Solver solver = new Solver("TestConstraint");
718  Assert.NotNull(solver);
719  IntVar x = solver.MakeIntVar(new int[] { 2, 4, -1, 6, 11, 10 }, "x");
720  Constraint ct = new SetMinAndMaxConstraint(solver, x);
721  solver.Add(ct);
722  DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
723  solver.NewSearch(db);
724  Assert.Equal(-1, x.Min());
725  Assert.Equal(11, x.Max());
726 
727  Assert.True(solver.NextSolution());
728  Assert.Equal(6, x.Min());
729  Assert.Equal(6, x.Max());
730 
731  Assert.True(solver.NextSolution());
732  Assert.Equal(10, x.Min());
733  Assert.Equal(10, x.Max());
734 
735  Assert.False(solver.NextSolution());
736  solver.EndSearch();
737  }
738 
739  // // This constraint has a single target variable x. It enforces x >= 5,
740  // but only at the leaf of the search tree: it doesn't change x's bounds,
741  // and simply fails if x is bound and is < 5.
742  class DumbGreaterOrEqualToFive : NetConstraint
743  {
744  public DumbGreaterOrEqualToFive(Solver solver, IntVar x) : base(solver)
745  {
746  x_ = x;
747  }
748  public override void Post()
749  {
750  demon_ = solver().MakeConstraintInitialPropagateCallback(this);
751  x_.WhenRange(demon_);
752  }
753  public override void InitialPropagate()
754  {
755  if (x_.Bound())
756  {
757  if (x_.Value() < 5)
758  {
759  solver().Fail();
760  }
761  }
762  }
763  private IntVar x_;
764  private Demon demon_;
765  }
766 
767  [Fact]
768  public void FailingConstraint()
769  {
770  Solver solver = new Solver("TestConstraint");
771  Assert.NotNull(solver);
772  IntVar x = solver.MakeIntVar(new int[] { 2, 4, -1, 6, 11, 10 }, "x");
773  Constraint ct = new DumbGreaterOrEqualToFive(solver, x);
774  solver.Add(ct);
775  DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
776  solver.NewSearch(db);
777  Assert.True(solver.NextSolution());
778  Assert.Equal(6, x.Min());
779  solver.EndSearch();
780  }
781 
782  [Fact]
783  public void DomainIterator()
784  {
785  Solver solver = new Solver("TestConstraint");
786  Assert.NotNull(solver);
787  IntVar x = solver.MakeIntVar(new int[] { 2, 4, -1, 6, 11, 10 }, "x");
788  ulong count = 0;
789  foreach (long value in x.GetDomain())
790  {
791  count++;
792  }
793  Assert.Equal(count, x.Size());
794  }
795 
796  class CountHoles : NetDemon
797  {
798  public CountHoles(IntVar x)
799  {
800  x_ = x;
801  count_ = 0;
802  }
803  public override void Run(Solver s)
804  {
805  foreach (long removed in x_.GetHoles())
806  {
807  count_++;
808  }
809  }
810  public int count()
811  {
812  return count_;
813  }
814  private IntVar x_;
815  private int count_;
816  }
817 
818  class RemoveThreeValues : NetConstraint
819  {
820  public RemoveThreeValues(Solver solver, IntVar x) : base(solver)
821  {
822  x_ = x;
823  }
824  public override void Post()
825  {
826  demon_ = new CountHoles(x_);
827  x_.WhenDomain(demon_);
828  }
829  public override void InitialPropagate()
830  {
831  x_.RemoveValues(new long[] { 3, 5, 7 });
832  }
833  public int count()
834  {
835  return demon_.count();
836  }
837  private IntVar x_;
838  private CountHoles demon_;
839  }
840 
841  [Fact]
842  public void HoleIteratorTest()
843  {
844  Solver solver = new Solver("TestConstraint");
845  Assert.NotNull(solver);
846  IntVar x = solver.MakeIntVar(0, 10, "x");
847  RemoveThreeValues ct = new RemoveThreeValues(solver, x);
848  solver.Add(ct);
849  DecisionBuilder db = solver.MakePhase(x, Solver.CHOOSE_FIRST_UNBOUND, Solver.ASSIGN_MIN_VALUE);
850  solver.Solve(db);
851  Assert.Equal(3, ct.count());
852  }
853 
854  // TODO(user): Improve search log tests; currently only tests coverage.
855  void RunSearchLog(in SearchMonitor searchlog)
856  {
857  searchlog.EnterSearch();
858  searchlog.ExitSearch();
859  searchlog.AcceptSolution();
860  searchlog.AtSolution();
861  searchlog.BeginFail();
862  searchlog.NoMoreSolutions();
863  searchlog.BeginInitialPropagation();
864  searchlog.EndInitialPropagation();
865  }
866 
867  [Fact]
868  public void SearchLog()
869  {
870  Solver solver = new Solver("TestSearchLog");
871  Assert.NotNull(solver);
872  IntVar var = solver.MakeIntVar(1, 1, "Variable");
873  OptimizeVar objective = solver.MakeMinimize(var, 1);
874  SearchMonitor searchlog = solver.MakeSearchLog(0);
875  RunSearchLog(in searchlog);
876  GC.KeepAlive(solver);
877  }
878 
879  [Theory]
880  [InlineData(false)]
881  [InlineData(true)]
882  public void SearchLogWithCallback(bool callGC)
883  {
884  Solver solver = new Solver("TestSearchLog");
885  Assert.NotNull(solver);
886  IntVar var = solver.MakeIntVar(1, 1, "Variable");
887  OptimizeVar objective = solver.MakeMinimize(var, 1);
888  int count = 0;
889  SearchMonitor searchlog = solver.MakeSearchLog(0, // branch period
890  () =>
891  {
892  count++;
893  return "display callback...";
894  });
895  if (callGC)
896  {
897  GC.Collect();
898  GC.WaitForPendingFinalizers();
899  }
900  RunSearchLog(in searchlog);
901  GC.KeepAlive(solver);
902  Assert.Equal(1, count);
903  }
904 
905  [Theory]
906  [InlineData(false)]
907  [InlineData(true)]
908  public void SearchLogWithObjectiveAndCallback(bool callGC)
909  {
910  Solver solver = new Solver("TestSearchLog");
911  Assert.NotNull(solver);
912  IntVar var = solver.MakeIntVar(1, 1, "Variable");
913  OptimizeVar objective = solver.MakeMinimize(var, 1);
914  int count = 0;
915  SearchMonitor searchlog = solver.MakeSearchLog(0, // branch period
916  objective, // objective var to monitor
917  () =>
918  {
919  count++;
920  return "OptimizeVar display callback";
921  });
922  if (callGC)
923  {
924  GC.Collect();
925  GC.WaitForPendingFinalizers();
926  }
927  RunSearchLog(in searchlog);
928  GC.KeepAlive(solver);
929  Assert.Equal(1, count);
930  }
931 
932  [Theory]
933  [InlineData(false)]
934  [InlineData(true)]
935  public void SearchLogWithIntVarAndCallback(bool callGC)
936  {
937  Solver solver = new Solver("TestSearchLog");
938  Assert.NotNull(solver);
939  IntVar var = solver.MakeIntVar(1, 1, "Variable");
940  OptimizeVar objective = solver.MakeMinimize(var, 1);
941  int count = 0;
942  SearchMonitor searchlog = solver.MakeSearchLog(0, // branch period
943  var, // int var to monitor
944  () =>
945  {
946  count++;
947  return "IntVar display callback";
948  });
949  if (callGC)
950  {
951  GC.Collect();
952  GC.WaitForPendingFinalizers();
953  }
954  RunSearchLog(in searchlog);
955  GC.KeepAlive(solver);
956  Assert.Equal(1, count);
957  }
958 }
959 } // namespace Google.OrTools.Tests
virtual void Run(Solver solver)
This is the new method to subclass when defining a .Net decision builder.
IntervalVar[] MakeFixedDurationIntervalVarArray(int count, long start_min, long start_max, long duration, bool optional)