OLD | NEW |
1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 Google Inc. All Rights Reserved. |
2 // Copyright 1996 John Maloney and Mario Wolczko | 2 // Copyright 1996 John Maloney and Mario Wolczko |
3 // | 3 // |
4 // This file is part of GNU Smalltalk. | 4 // This file is part of GNU Smalltalk. |
5 // | 5 // |
6 // GNU Smalltalk is free software; you can redistribute it and/or modify it | 6 // GNU Smalltalk is free software; you can redistribute it and/or modify it |
7 // under the terms of the GNU General Public License as published by the Free | 7 // under the terms of the GNU General Public License as published by the Free |
8 // Software Foundation; either version 2, or (at your option) any later version. | 8 // Software Foundation; either version 2, or (at your option) any later version. |
9 // | 9 // |
10 // GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT | 10 // GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT |
(...skipping 28 matching lines...) Expand all Loading... |
39 } | 39 } |
40 | 40 |
41 /// Benchmark class required to report results. | 41 /// Benchmark class required to report results. |
42 class DeltaBlue { | 42 class DeltaBlue { |
43 void run() { | 43 void run() { |
44 chainTest(100); | 44 chainTest(100); |
45 projectionTest(100); | 45 projectionTest(100); |
46 } | 46 } |
47 } | 47 } |
48 | 48 |
49 | |
50 /** | 49 /** |
51 * Strengths are used to measure the relative importance of constraints. | 50 * Strengths are used to measure the relative importance of constraints. |
52 * New strengths may be inserted in the strength hierarchy without | 51 * New strengths may be inserted in the strength hierarchy without |
53 * disrupting current constraints. Strengths cannot be created outside | 52 * disrupting current constraints. Strengths cannot be created outside |
54 * this class, so == can be used for value comparison. | 53 * this class, so == can be used for value comparison. |
55 */ | 54 */ |
56 class Strength { | 55 class Strength { |
57 | |
58 final int value; | 56 final int value; |
59 final String name; | 57 final String name; |
60 | 58 |
61 const Strength(this.value, this.name); | 59 const Strength(this.value, this.name); |
62 | 60 |
63 Strength nextWeaker() => | 61 Strength nextWeaker() => const <Strength>[ |
64 const <Strength>[STRONG_PREFERRED, PREFERRED, STRONG_DEFAULT, NORMAL, | 62 STRONG_PREFERRED, |
65 WEAK_DEFAULT, WEAKEST][value]; | 63 PREFERRED, |
| 64 STRONG_DEFAULT, |
| 65 NORMAL, |
| 66 WEAK_DEFAULT, |
| 67 WEAKEST |
| 68 ][value]; |
66 | 69 |
67 static bool stronger(Strength s1, Strength s2) { | 70 static bool stronger(Strength s1, Strength s2) { |
68 return s1.value < s2.value; | 71 return s1.value < s2.value; |
69 } | 72 } |
70 | 73 |
71 static bool weaker(Strength s1, Strength s2) { | 74 static bool weaker(Strength s1, Strength s2) { |
72 return s1.value > s2.value; | 75 return s1.value > s2.value; |
73 } | 76 } |
74 | 77 |
75 static Strength weakest(Strength s1, Strength s2) { | 78 static Strength weakest(Strength s1, Strength s2) { |
76 return weaker(s1, s2) ? s1 : s2; | 79 return weaker(s1, s2) ? s1 : s2; |
77 } | 80 } |
78 | 81 |
79 static Strength strongest(Strength s1, Strength s2) { | 82 static Strength strongest(Strength s1, Strength s2) { |
80 return stronger(s1, s2) ? s1 : s2; | 83 return stronger(s1, s2) ? s1 : s2; |
81 } | 84 } |
82 } | 85 } |
83 | 86 |
84 | |
85 // Compile time computed constants. | 87 // Compile time computed constants. |
86 const REQUIRED = const Strength(0, "required"); | 88 const REQUIRED = const Strength(0, "required"); |
87 const STRONG_PREFERRED = const Strength(1, "strongPreferred"); | 89 const STRONG_PREFERRED = const Strength(1, "strongPreferred"); |
88 const PREFERRED = const Strength(2, "preferred"); | 90 const PREFERRED = const Strength(2, "preferred"); |
89 const STRONG_DEFAULT = const Strength(3, "strongDefault"); | 91 const STRONG_DEFAULT = const Strength(3, "strongDefault"); |
90 const NORMAL = const Strength(4, "normal"); | 92 const NORMAL = const Strength(4, "normal"); |
91 const WEAK_DEFAULT = const Strength(5, "weakDefault"); | 93 const WEAK_DEFAULT = const Strength(5, "weakDefault"); |
92 const WEAKEST = const Strength(6, "weakest"); | 94 const WEAKEST = const Strength(6, "weakest"); |
93 | |
94 | 95 |
95 abstract class Constraint { | 96 abstract class Constraint { |
96 | |
97 final Strength strength; | 97 final Strength strength; |
98 | 98 |
99 const Constraint(this.strength); | 99 const Constraint(this.strength); |
100 | 100 |
101 bool isSatisfied(); | 101 bool isSatisfied(); |
102 void markUnsatisfied(); | 102 void markUnsatisfied(); |
103 void addToGraph(); | 103 void addToGraph(); |
104 void removeFromGraph(); | 104 void removeFromGraph(); |
105 void chooseMethod(int mark); | 105 void chooseMethod(int mark); |
106 void markInputs(int mark); | 106 void markInputs(int mark); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 * is one that depends on external state, such as the mouse, the | 150 * is one that depends on external state, such as the mouse, the |
151 * keybord, a clock, or some arbitraty piece of imperative code. | 151 * keybord, a clock, or some arbitraty piece of imperative code. |
152 */ | 152 */ |
153 bool isInput() => false; | 153 bool isInput() => false; |
154 } | 154 } |
155 | 155 |
156 /** | 156 /** |
157 * Abstract superclass for constraints having a single possible output variable. | 157 * Abstract superclass for constraints having a single possible output variable. |
158 */ | 158 */ |
159 abstract class UnaryConstraint extends Constraint { | 159 abstract class UnaryConstraint extends Constraint { |
160 | |
161 final Variable myOutput; | 160 final Variable myOutput; |
162 bool satisfied = false; | 161 bool satisfied = false; |
163 | 162 |
164 UnaryConstraint(this.myOutput, Strength strength) : super(strength) { | 163 UnaryConstraint(this.myOutput, Strength strength) : super(strength) { |
165 addConstraint(); | 164 addConstraint(); |
166 } | 165 } |
167 | 166 |
168 /// Adds this constraint to the constraint graph | 167 /// Adds this constraint to the constraint graph |
169 void addToGraph() { | 168 void addToGraph() { |
170 myOutput.addConstraint(this); | 169 myOutput.addConstraint(this); |
171 satisfied = false; | 170 satisfied = false; |
172 } | 171 } |
173 | 172 |
174 /// Decides if this constraint can be satisfied and records that decision. | 173 /// Decides if this constraint can be satisfied and records that decision. |
175 void chooseMethod(int mark) { | 174 void chooseMethod(int mark) { |
176 satisfied = (myOutput.mark != mark) | 175 satisfied = (myOutput.mark != mark) && |
177 && Strength.stronger(strength, myOutput.walkStrength); | 176 Strength.stronger(strength, myOutput.walkStrength); |
178 } | 177 } |
179 | 178 |
180 /// Returns true if this constraint is satisfied in the current solution. | 179 /// Returns true if this constraint is satisfied in the current solution. |
181 bool isSatisfied() => satisfied; | 180 bool isSatisfied() => satisfied; |
182 | 181 |
183 void markInputs(int mark) { | 182 void markInputs(int mark) { |
184 // has no inputs. | 183 // has no inputs. |
185 } | 184 } |
186 | 185 |
187 /// Returns the current output variable. | 186 /// Returns the current output variable. |
(...skipping 16 matching lines...) Expand all Loading... |
204 } | 203 } |
205 | 204 |
206 bool inputsKnown(int mark) => true; | 205 bool inputsKnown(int mark) => true; |
207 | 206 |
208 void removeFromGraph() { | 207 void removeFromGraph() { |
209 if (myOutput != null) myOutput.removeConstraint(this); | 208 if (myOutput != null) myOutput.removeConstraint(this); |
210 satisfied = false; | 209 satisfied = false; |
211 } | 210 } |
212 } | 211 } |
213 | 212 |
214 | |
215 /** | 213 /** |
216 * Variables that should, with some level of preference, stay the same. | 214 * Variables that should, with some level of preference, stay the same. |
217 * Planners may exploit the fact that instances, if satisfied, will not | 215 * Planners may exploit the fact that instances, if satisfied, will not |
218 * change their output during plan execution. This is called "stay | 216 * change their output during plan execution. This is called "stay |
219 * optimization". | 217 * optimization". |
220 */ | 218 */ |
221 class StayConstraint extends UnaryConstraint { | 219 class StayConstraint extends UnaryConstraint { |
222 | |
223 StayConstraint(Variable v, Strength str) : super(v, str); | 220 StayConstraint(Variable v, Strength str) : super(v, str); |
224 | 221 |
225 void execute() { | 222 void execute() { |
226 // Stay constraints do nothing. | 223 // Stay constraints do nothing. |
227 } | 224 } |
228 } | 225 } |
229 | 226 |
230 | |
231 /** | 227 /** |
232 * A unary input constraint used to mark a variable that the client | 228 * A unary input constraint used to mark a variable that the client |
233 * wishes to change. | 229 * wishes to change. |
234 */ | 230 */ |
235 class EditConstraint extends UnaryConstraint { | 231 class EditConstraint extends UnaryConstraint { |
236 | |
237 EditConstraint(Variable v, Strength str) : super(v, str); | 232 EditConstraint(Variable v, Strength str) : super(v, str); |
238 | 233 |
239 /// Edits indicate that a variable is to be changed by imperative code. | 234 /// Edits indicate that a variable is to be changed by imperative code. |
240 bool isInput() => true; | 235 bool isInput() => true; |
241 | 236 |
242 void execute() { | 237 void execute() { |
243 // Edit constraints do nothing. | 238 // Edit constraints do nothing. |
244 } | 239 } |
245 } | 240 } |
246 | 241 |
247 | |
248 // Directions. | 242 // Directions. |
249 const int NONE = 1; | 243 const int NONE = 1; |
250 const int FORWARD = 2; | 244 const int FORWARD = 2; |
251 const int BACKWARD = 0; | 245 const int BACKWARD = 0; |
252 | 246 |
253 | |
254 /** | 247 /** |
255 * Abstract superclass for constraints having two possible output | 248 * Abstract superclass for constraints having two possible output |
256 * variables. | 249 * variables. |
257 */ | 250 */ |
258 abstract class BinaryConstraint extends Constraint { | 251 abstract class BinaryConstraint extends Constraint { |
259 | |
260 Variable v1; | 252 Variable v1; |
261 Variable v2; | 253 Variable v2; |
262 int direction = NONE; | 254 int direction = NONE; |
263 | 255 |
264 BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) { | 256 BinaryConstraint(this.v1, this.v2, Strength strength) : super(strength) { |
265 addConstraint(); | 257 addConstraint(); |
266 } | 258 } |
267 | 259 |
268 /** | 260 /** |
269 * Decides if this constraint can be satisfied and which way it | 261 * Decides if this constraint can be satisfied and which way it |
270 * should flow based on the relative strength of the variables related, | 262 * should flow based on the relative strength of the variables related, |
271 * and record that decision. | 263 * and record that decision. |
272 */ | 264 */ |
273 void chooseMethod(int mark) { | 265 void chooseMethod(int mark) { |
274 if (v1.mark == mark) { | 266 if (v1.mark == mark) { |
275 direction = (v2.mark != mark && | 267 direction = |
276 Strength.stronger(strength, v2.walkStrength)) | 268 (v2.mark != mark && Strength.stronger(strength, v2.walkStrength)) |
277 ? FORWARD : NONE; | 269 ? FORWARD |
| 270 : NONE; |
278 } | 271 } |
279 if (v2.mark == mark) { | 272 if (v2.mark == mark) { |
280 direction = (v1.mark != mark && | 273 direction = |
281 Strength.stronger(strength, v1.walkStrength)) | 274 (v1.mark != mark && Strength.stronger(strength, v1.walkStrength)) |
282 ? BACKWARD : NONE; | 275 ? BACKWARD |
| 276 : NONE; |
283 } | 277 } |
284 if (Strength.weaker(v1.walkStrength, v2.walkStrength)) { | 278 if (Strength.weaker(v1.walkStrength, v2.walkStrength)) { |
285 direction = Strength.stronger(strength, v1.walkStrength) | 279 direction = |
286 ? BACKWARD : NONE; | 280 Strength.stronger(strength, v1.walkStrength) ? BACKWARD : NONE; |
287 } else { | 281 } else { |
288 direction = Strength.stronger(strength, v2.walkStrength) | 282 direction = |
289 ? FORWARD : BACKWARD; | 283 Strength.stronger(strength, v2.walkStrength) ? FORWARD : BACKWARD; |
290 } | 284 } |
291 } | 285 } |
292 | 286 |
293 /// Add this constraint to the constraint graph. | 287 /// Add this constraint to the constraint graph. |
294 void addToGraph() { | 288 void addToGraph() { |
295 v1.addConstraint(this); | 289 v1.addConstraint(this); |
296 v2.addConstraint(this); | 290 v2.addConstraint(this); |
297 direction = NONE; | 291 direction = NONE; |
298 } | 292 } |
299 | 293 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 return i.mark == mark || i.stay || i.determinedBy == null; | 327 return i.mark == mark || i.stay || i.determinedBy == null; |
334 } | 328 } |
335 | 329 |
336 void removeFromGraph() { | 330 void removeFromGraph() { |
337 if (v1 != null) v1.removeConstraint(this); | 331 if (v1 != null) v1.removeConstraint(this); |
338 if (v2 != null) v2.removeConstraint(this); | 332 if (v2 != null) v2.removeConstraint(this); |
339 direction = NONE; | 333 direction = NONE; |
340 } | 334 } |
341 } | 335 } |
342 | 336 |
343 | |
344 /** | 337 /** |
345 * Relates two variables by the linear scaling relationship: "v2 = | 338 * Relates two variables by the linear scaling relationship: "v2 = |
346 * (v1 * scale) + offset". Either v1 or v2 may be changed to maintain | 339 * (v1 * scale) + offset". Either v1 or v2 may be changed to maintain |
347 * this relationship but the scale factor and offset are considered | 340 * this relationship but the scale factor and offset are considered |
348 * read-only. | 341 * read-only. |
349 */ | 342 */ |
350 | 343 |
351 class ScaleConstraint extends BinaryConstraint { | 344 class ScaleConstraint extends BinaryConstraint { |
352 | |
353 final Variable scale; | 345 final Variable scale; |
354 final Variable offset; | 346 final Variable offset; |
355 | 347 |
356 ScaleConstraint(Variable src, this.scale, this.offset, | 348 ScaleConstraint( |
357 Variable dest, Strength strength) | 349 Variable src, this.scale, this.offset, Variable dest, Strength strength) |
358 : super(src, dest, strength); | 350 : super(src, dest, strength); |
359 | 351 |
360 /// Adds this constraint to the constraint graph. | 352 /// Adds this constraint to the constraint graph. |
361 void addToGraph() { | 353 void addToGraph() { |
362 super.addToGraph(); | 354 super.addToGraph(); |
363 scale.addConstraint(this); | 355 scale.addConstraint(this); |
364 offset.addConstraint(this); | 356 offset.addConstraint(this); |
365 } | 357 } |
366 | 358 |
367 void removeFromGraph() { | 359 void removeFromGraph() { |
368 super.removeFromGraph(); | 360 super.removeFromGraph(); |
(...skipping 19 matching lines...) Expand all Loading... |
388 * Calculate the walkabout strength, the stay flag, and, if it is | 380 * Calculate the walkabout strength, the stay flag, and, if it is |
389 * 'stay', the value for the current output of this constraint. Assume | 381 * 'stay', the value for the current output of this constraint. Assume |
390 * this constraint is satisfied. | 382 * this constraint is satisfied. |
391 */ | 383 */ |
392 void recalculate() { | 384 void recalculate() { |
393 Variable ihn = input(), out = output(); | 385 Variable ihn = input(), out = output(); |
394 out.walkStrength = Strength.weakest(strength, ihn.walkStrength); | 386 out.walkStrength = Strength.weakest(strength, ihn.walkStrength); |
395 out.stay = ihn.stay && scale.stay && offset.stay; | 387 out.stay = ihn.stay && scale.stay && offset.stay; |
396 if (out.stay) execute(); | 388 if (out.stay) execute(); |
397 } | 389 } |
398 | |
399 } | 390 } |
400 | 391 |
401 | |
402 /** | 392 /** |
403 * Constrains two variables to have the same value. | 393 * Constrains two variables to have the same value. |
404 */ | 394 */ |
405 class EqualityConstraint extends BinaryConstraint { | 395 class EqualityConstraint extends BinaryConstraint { |
406 | |
407 EqualityConstraint(Variable v1, Variable v2, Strength strength) | 396 EqualityConstraint(Variable v1, Variable v2, Strength strength) |
408 : super(v1, v2, strength); | 397 : super(v1, v2, strength); |
409 | 398 |
410 /// Enforce this constraint. Assume that it is satisfied. | 399 /// Enforce this constraint. Assume that it is satisfied. |
411 void execute() { | 400 void execute() { |
412 output().value = input().value; | 401 output().value = input().value; |
413 } | 402 } |
414 } | 403 } |
415 | 404 |
416 | |
417 /** | 405 /** |
418 * A constrained variable. In addition to its value, it maintain the | 406 * A constrained variable. In addition to its value, it maintain the |
419 * structure of the constraint graph, the current dataflow graph, and | 407 * structure of the constraint graph, the current dataflow graph, and |
420 * various parameters of interest to the DeltaBlue incremental | 408 * various parameters of interest to the DeltaBlue incremental |
421 * constraint solver. | 409 * constraint solver. |
422 **/ | 410 **/ |
423 class Variable { | 411 class Variable { |
424 | |
425 List<Constraint> constraints = <Constraint>[]; | 412 List<Constraint> constraints = <Constraint>[]; |
426 Constraint determinedBy; | 413 Constraint determinedBy; |
427 int mark = 0; | 414 int mark = 0; |
428 Strength walkStrength = WEAKEST; | 415 Strength walkStrength = WEAKEST; |
429 bool stay = true; | 416 bool stay = true; |
430 int value; | 417 int value; |
431 final String name; | 418 final String name; |
432 | 419 |
433 Variable(this.name, this.value); | 420 Variable(this.name, this.value); |
434 | 421 |
435 /** | 422 /** |
436 * Add the given constraint to the set of all constraints that refer | 423 * Add the given constraint to the set of all constraints that refer |
437 * this variable. | 424 * this variable. |
438 */ | 425 */ |
439 void addConstraint(Constraint c) { | 426 void addConstraint(Constraint c) { |
440 constraints.add(c); | 427 constraints.add(c); |
441 } | 428 } |
442 | 429 |
443 /// Removes all traces of c from this variable. | 430 /// Removes all traces of c from this variable. |
444 void removeConstraint(Constraint c) { | 431 void removeConstraint(Constraint c) { |
445 constraints.remove(c); | 432 constraints.remove(c); |
446 if (determinedBy == c) determinedBy = null; | 433 if (determinedBy == c) determinedBy = null; |
447 } | 434 } |
448 } | 435 } |
449 | 436 |
450 | |
451 class Planner { | 437 class Planner { |
452 | |
453 int currentMark = 0; | 438 int currentMark = 0; |
454 | 439 |
455 /** | 440 /** |
456 * Attempt to satisfy the given constraint and, if successful, | 441 * Attempt to satisfy the given constraint and, if successful, |
457 * incrementally update the dataflow graph. Details: If satifying | 442 * incrementally update the dataflow graph. Details: If satifying |
458 * the constraint is successful, it may override a weaker constraint | 443 * the constraint is successful, it may override a weaker constraint |
459 * on its output. The algorithm attempts to resatisfy that | 444 * on its output. The algorithm attempts to resatisfy that |
460 * constraint using some other method. This process is repeated | 445 * constraint using some other method. This process is repeated |
461 * until either a) it reaches a variable that was not previously | 446 * until either a) it reaches a variable that was not previously |
462 * determined by any constraint or b) it reaches a constraint that | 447 * determined by any constraint or b) it reaches a constraint that |
463 * is too weak to be satisfied using any of its methods. The | 448 * is too weak to be satisfied using any of its methods. The |
464 * variables of constraints that have been processed are marked with | 449 * variables of constraints that have been processed are marked with |
465 * a unique mark value so that we know where we've been. This allows | 450 * a unique mark value so that we know where we've been. This allows |
466 * the algorithm to avoid getting into an infinite loop even if the | 451 * the algorithm to avoid getting into an infinite loop even if the |
467 * constraint graph has an inadvertent cycle. | 452 * constraint graph has an inadvertent cycle. |
468 */ | 453 */ |
469 void incrementalAdd(Constraint c) { | 454 void incrementalAdd(Constraint c) { |
470 int mark = newMark(); | 455 int mark = newMark(); |
471 for(Constraint overridden = c.satisfy(mark); | 456 for (Constraint overridden = c.satisfy(mark); |
472 overridden != null; | 457 overridden != null; |
473 overridden = overridden.satisfy(mark)); | 458 overridden = overridden.satisfy(mark)); |
474 } | 459 } |
475 | 460 |
476 /** | 461 /** |
477 * Entry point for retracting a constraint. Remove the given | 462 * Entry point for retracting a constraint. Remove the given |
478 * constraint and incrementally update the dataflow graph. | 463 * constraint and incrementally update the dataflow graph. |
479 * Details: Retracting the given constraint may allow some currently | 464 * Details: Retracting the given constraint may allow some currently |
480 * unsatisfiable downstream constraint to be satisfied. We therefore collect | 465 * unsatisfiable downstream constraint to be satisfied. We therefore collect |
481 * a list of unsatisfied downstream constraints and attempt to | 466 * a list of unsatisfied downstream constraints and attempt to |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
608 | 593 |
609 void addConstraintsConsumingTo(Variable v, List<Constraint> coll) { | 594 void addConstraintsConsumingTo(Variable v, List<Constraint> coll) { |
610 Constraint determining = v.determinedBy; | 595 Constraint determining = v.determinedBy; |
611 for (int i = 0; i < v.constraints.length; i++) { | 596 for (int i = 0; i < v.constraints.length; i++) { |
612 Constraint c = v.constraints[i]; | 597 Constraint c = v.constraints[i]; |
613 if (c != determining && c.isSatisfied()) coll.add(c); | 598 if (c != determining && c.isSatisfied()) coll.add(c); |
614 } | 599 } |
615 } | 600 } |
616 } | 601 } |
617 | 602 |
618 | |
619 /** | 603 /** |
620 * A Plan is an ordered list of constraints to be executed in sequence | 604 * A Plan is an ordered list of constraints to be executed in sequence |
621 * to resatisfy all currently satisfiable constraints in the face of | 605 * to resatisfy all currently satisfiable constraints in the face of |
622 * one or more changing inputs. | 606 * one or more changing inputs. |
623 */ | 607 */ |
624 class Plan { | 608 class Plan { |
625 List<Constraint> list = <Constraint>[]; | 609 List<Constraint> list = <Constraint>[]; |
626 | 610 |
627 void addConstraint(Constraint c) { | 611 void addConstraint(Constraint c) { |
628 list.add(c); | 612 list.add(c); |
629 } | 613 } |
630 | 614 |
631 int size() => list.length; | 615 int size() => list.length; |
632 | 616 |
633 void execute() { | 617 void execute() { |
634 for (int i = 0; i < list.length; i++) { | 618 for (int i = 0; i < list.length; i++) { |
635 list[i].execute(); | 619 list[i].execute(); |
636 } | 620 } |
637 } | 621 } |
638 } | 622 } |
639 | 623 |
640 | |
641 /** | 624 /** |
642 * This is the standard DeltaBlue benchmark. A long chain of equality | 625 * This is the standard DeltaBlue benchmark. A long chain of equality |
643 * constraints is constructed with a stay constraint on one end. An | 626 * constraints is constructed with a stay constraint on one end. An |
644 * edit constraint is then added to the opposite end and the time is | 627 * edit constraint is then added to the opposite end and the time is |
645 * measured for adding and removing this constraint, and extracting | 628 * measured for adding and removing this constraint, and extracting |
646 * and executing a constraint satisfaction plan. There are two cases. | 629 * and executing a constraint satisfaction plan. There are two cases. |
647 * In case 1, the added constraint is stronger than the stay | 630 * In case 1, the added constraint is stronger than the stay |
648 * constraint and values must propagate down the entire length of the | 631 * constraint and values must propagate down the entire length of the |
649 * chain. In case 2, the added constraint is weaker than the stay | 632 * chain. In case 2, the added constraint is weaker than the stay |
650 * constraint so it cannot be accomodated. The cost in this case is, | 633 * constraint so it cannot be accomodated. The cost in this case is, |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 EditConstraint edit = new EditConstraint(v, PREFERRED); | 696 EditConstraint edit = new EditConstraint(v, PREFERRED); |
714 Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]); | 697 Plan plan = planner.extractPlanFromConstraints(<EditConstraint>[edit]); |
715 for (int i = 0; i < 10; i++) { | 698 for (int i = 0; i < 10; i++) { |
716 v.value = newValue; | 699 v.value = newValue; |
717 plan.execute(); | 700 plan.execute(); |
718 } | 701 } |
719 edit.destroyConstraint(); | 702 edit.destroyConstraint(); |
720 } | 703 } |
721 | 704 |
722 Planner planner; | 705 Planner planner; |
OLD | NEW |