public UpdateDomain ( |
||
d | the domain to be updated with | |
trail | the trail to be pushed | |
return | void |
private static bool SatisfyNEGATE(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; if (d1.Size() == 1) { // v0 = -v1 int value = -d1.Value(); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { v0.UpdateDomain(new IntDomain(value), trail); } return(true); } if (d0.Size() == 1) { // v1 = -v0 int value = -d0.Value(); if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } // v0 = -v1 d0 = d0.CapInterval(-d1.Maximum(), -d1.Minimum()); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = -v0 d1 = d1.CapInterval(-d0.Maximum(), -d0.Minimum()); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfyLE(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; d0 = d0.CapInterval(IntDomain.MinValue, d1.Maximum()); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } d1 = d1.CapInterval(d0.Minimum(), IntDomain.MaxValue); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfyMULTIPLY(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 * v2 int value = ToInt(d1.Value() * (long) d2.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 / v2 int x = d0.Value(); int y = d2.Value(); if (y == 0) { return x == 0; } if (x % y != 0) { return false; } int value = x / y; if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 / v1 int x = d0.Value(); int y = d1.Value(); if (y == 0) { return x == 0; } if (x % y != 0) { return false; } int value = x / y; if (!d2.Contains(value)) return false; if (d2.Size() > 1) if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } return true; } d0 = Multiply(d0, d1, d2); if (d0.Empty) return false; d1 = Divide(d1, d0, d2); if (d1.Empty) return false; d2 = Divide(d2, d0, d1); if (d2.Empty) return false; if (trail != null) { if (d0 != v0.Domain) v0.UpdateDomain(d0, trail); if (d1 != v1.Domain) v1.UpdateDomain(d1, trail); if (d2 != v2.Domain) v2.UpdateDomain(d2, trail); } return true; }
private static bool SatisfyMIN(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = Min(v1, v2) int value = Math.Min(d1.Value(), d2.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { int value = d0.Value(); if (!d1.Contains(value) && !d2.Contains(value)) return false; // ??? if (d1.Minimum() < value) { d1.CapInterval(value, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } if (d2.Minimum() < value) { d2.CapInterval(value, IntDomain.MaxValue); if (d2.Empty) return false; if (trail != null) { v2.UpdateDomain(d2, trail); } } return true; } // v0 = Min(v1, v2) int min = Math.Min(d1.Minimum(), d2.Minimum()); int max = Math.Min(d1.Maximum(), d2.Maximum()); d0 = d0.CapInterval(min, max); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // if (d1.Minimum() < d0.Minimum()) d1 = d1.CapInterval(d0.Minimum(), IntDomain.MaxValue); if (d2.Minimum() < d0.Minimum()) d2 = d2.CapInterval(d0.Minimum(), IntDomain.MaxValue); if (d1.Minimum() > d0.Maximum()) { d0 = (IntDomain) d0.Cap(d2); d2 = d0; } if (d2.Minimum() > d0.Maximum()) { d0 = (IntDomain) d0.Cap(d1); d1 = d0; } if (d0.Empty) return false; if (d1.Empty) return false; if (d2.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); v2.UpdateDomain(d2, trail); } return true; }
private static bool SatisfyAdd(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; var d2 = (IntDomain) v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 + v2 var value = d1.Value() + d2.Value(); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 - v2 var value = d0.Value() - d2.Value(); if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 - v1 var value = d0.Value() - d1.Value(); if (!d2.Contains(value)) return false; if (d2.Size() > 1) if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } return true; } // v0 = v1 + v2 d0 = d0.CapInterval(d1.Minimum() + d2.Minimum(), d1.Maximum() + d2.Maximum()); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = v0 - v2 d1 = d1.CapInterval(d0.Minimum() - d2.Maximum(), d0.Maximum() - d2.Minimum()); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } // v2 = v0 - v1 d2 = d2.CapInterval(d0.Minimum() - d1.Maximum(), d0.Maximum() - d1.Minimum()); if (d2.Empty) return false; if (trail != null) { v2.UpdateDomain(d2, trail); } return true; }
private static bool SatisfyLT(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; d0 = d0.CapInterval(IntDomain.MinValue, d1.Maximum() - 1); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } d1 = d1.CapInterval(d0.Minimum() + 1, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
private bool SatisfyMIN(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = Min(v1, v2) int value = Math.Min(d1.Value(), d2.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1) { int value = d0.Value(); if (!d1.Contains(value) && !d2.Contains(value)) { return(false); } // ??? if (d1.Minimum() < value) { d1.CapInterval(value, IntDomain.MaxValue); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } if (d2.Minimum() < value) { d2.CapInterval(value, IntDomain.MaxValue); if (d2.Empty) { return(false); } if (trail != null) { v2.UpdateDomain(d2, trail); } } return(true); } // v0 = Min(v1, v2) int min = Math.Min(d1.Minimum(), d2.Minimum()); int max = Math.Min(d1.Maximum(), d2.Maximum()); d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // if (d1.Minimum() < d0.Minimum()) { d1 = d1.CapInterval(d0.Minimum(), IntDomain.MaxValue); } if (d2.Minimum() < d0.Minimum()) { d2 = d2.CapInterval(d0.Minimum(), IntDomain.MaxValue); } if (d1.Minimum() > d0.Maximum()) { d0 = (IntDomain)d0.Cap(d2); d2 = d0; } if (d2.Minimum() > d0.Maximum()) { d0 = (IntDomain)d0.Cap(d1); d1 = d0; } if (d0.Empty) { return(false); } if (d1.Empty) { return(false); } if (d2.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); v2.UpdateDomain(d2, trail); } return(true); }
private bool SatisfyMULTIPLY(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 * v2 int value = ToInt(d1.Value() * (long)d2.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 / v2 int x = d0.Value(); int y = d2.Value(); if (y == 0) { return(x == 0); } if (x % y != 0) { return(false); } int value = x / y; if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 / v1 int x = d0.Value(); int y = d1.Value(); if (y == 0) { return(x == 0); } if (x % y != 0) { return(false); } int value = x / y; if (!d2.Contains(value)) { return(false); } if (d2.Size() > 1) { if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } } return(true); } d0 = Multiply(d0, d1, d2); if (d0.Empty) { return(false); } d1 = Divide(d1, d0, d2); if (d1.Empty) { return(false); } d2 = Divide(d2, d0, d1); if (d2.Empty) { return(false); } if (trail != null) { if (d0 != v0.Domain) { v0.UpdateDomain(d0, trail); } if (d1 != v1.Domain) { v1.UpdateDomain(d1, trail); } if (d2 != v2.Domain) { v2.UpdateDomain(d2, trail); } } return(true); }
private bool SatisfyADD(Variable v0, Variable v1, Variable v2, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; var d2 = (IntDomain)v2.Domain; int value; if (d1.Size() == 1 && d2.Size() == 1) { // v0 = v1 + v2 value = d1.Value() + d2.Value(); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } value = d0.Value() - d2.Value(); if (d0.Size() == 1 && d2.Size() == 1) { // v1 = v0 - v2 if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } value = d0.Value() - d1.Value(); if (d0.Size() == 1 && d1.Size() == 1) { // v2 = v0 - v1 if (!d2.Contains(value)) { return(false); } if (d2.Size() > 1) { if (trail != null) { v2.UpdateDomain(new IntDomain(value), trail); } } return(true); } // v0 = v1 + v2 d0 = d0.CapInterval(d1.Minimum() + d2.Minimum(), d1.Maximum() + d2.Maximum()); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = v0 - v2 d1 = d1.CapInterval(d0.Minimum() - d2.Maximum(), d0.Maximum() - d2.Minimum()); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } // v2 = v0 - v1 d2 = d2.CapInterval(d0.Minimum() - d1.Maximum(), d0.Maximum() - d1.Minimum()); if (d2.Empty) { return(false); } if (trail != null) { v2.UpdateDomain(d2, trail); } return(true); }
protected override internal bool Satisfy(Trail trail) { int m = rel.Length; int n = rel[0].Length; // limit the domain of v0 to 0..m-1 var d0 = (IntDomain)v0.Domain; d0 = d0.CapInterval(0, m - 1); if (d0.Empty) { return(false); } // limit the domain of v1 to 0..n-1 var d1 = (IntDomain)v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) { return(false); } // Delete impossible indices from v0 for (int i = 0; i < m; i++) { if (!d0.Contains(i)) { continue; } bool support = false; for (int j = 0; j < n; j++) { if (rel[i][j] && d1.Contains(j)) { support = true; break; } } if (!support) { d0 = d0.Delete(i); } } if (d0.Empty) { return(false); } // Delete impossible indices from v1 for (int j = 0; j < n; j++) { if (!d1.Contains(j)) { continue; } bool support = false; for (int i = 0; i < m; i++) { if (rel[i][j] && d0.Contains(i)) { support = true; break; } } if (!support) { d1 = d1.Delete(j); } } if (d1.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfySIGN(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = Sign(v1) int sign = 0; if (d1.Value() < 0) { sign = - 1; } else if (d1.Value() > 0) { sign = 1; } if (!d0.Contains(sign)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(sign), trail); } return true; } if (d0.Size() == 1) { // Sign(v1) = v0 int sign = d0.Value(); if (sign < 0) { if (d1.Maximum() >= 0) { d1 = d1.CapInterval(IntDomain.MinValue, - 1); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } if (sign == 0) { if (!d1.Contains(0)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(0), trail); } return true; } if (sign > 0) { if (d1.Minimum() <= 0) { d1 = d1.CapInterval(1, IntDomain.MaxValue); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } return false; } // v0 = Sign(v1) if (!(- 1 <= d0.Minimum() && d0.Maximum() <= 1)) { d0 = d0.CapInterval(- 1, 1); } if (d1.Minimum() >= 0) d0 = d0.Delete(- 1); if (!d1.Contains(0)) d0 = d0.Delete(0); if (d1.Maximum() <= 0) d0 = d0.Delete(1); // Sign(v1) = v0 if (!d0.Contains(- 1)) { if (d1.Minimum() < 0) d1 = d1.CapInterval(0, IntDomain.MaxValue); } if (!d0.Contains(0)) { d1 = d1.Delete(0); } if (!d0.Contains(1)) { if (d1.Maximum() > 0) d1 = d1.CapInterval(IntDomain.MinValue, 0); } if (d0.Empty) return false; if (d1.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfyNEGATE(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = -v1 int value = - d1.Value(); if (!d0.Contains(value)) return false; if (d0.Size() > 1) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { // v1 = -v0 int value = - d0.Value(); if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } // v0 = -v1 d0 = d0.CapInterval(- d1.Maximum(), - d1.Minimum()); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // v1 = -v0 d1 = d1.CapInterval(- d0.Maximum(), - d0.Minimum()); if (d1.Empty) return false; if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfyABS(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain) v0.Domain; var d1 = (IntDomain) v1.Domain; if (d1.Size() == 1) { // v0 = Abs(v1) int value = Math.Abs(d1.Value()); if (!d0.Contains(value)) return false; if (d0.Size() > 1) if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } return true; } if (d0.Size() == 1) { // Abs(v1) = v0 int value = d0.Value(); if (value < 0) { return false; } if (value == 0) { if (!d1.Contains(value)) return false; if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d1.Contains(value) && d1.Contains(- value)) { if (d1.Size() > 2) { value = Math.Abs(value); d1 = new IntDomain(- value, value); d1 = d1.Delete(- value + 1, value - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } } return true; } if (d1.Contains(value)) { if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } return true; } if (d1.Contains(- value)) { if (d1.Size() > 1) if (trail != null) { v1.UpdateDomain(new IntDomain(-value), trail); } return true; } return false; } int min; int max; // v0 = Abs(v1) if (d1.Minimum() >= 0) { min = d1.Minimum(); max = d1.Maximum(); } else if (d1.Maximum() <= 0) { min = - d1.Maximum(); max = - d1.Minimum(); } else { min = 0; max = Math.Max(- d1.Minimum(), d1.Maximum()); } d0 = d0.CapInterval(min, max); if (d0.Empty) return false; if (trail != null) { v0.UpdateDomain(d0, trail); } // Abs(v1) = v0 min = d0.Minimum(); max = d0.Maximum(); d1 = d1.CapInterval(- max, max); if (d1.Empty) return false; if (min > 0) d1 = d1.Delete(- min + 1, min - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } return true; }
private static bool SatisfySIGN(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; if (d1.Size() == 1) { // v0 = Sign(v1) int sign = 0; if (d1.Value() < 0) { sign = -1; } else if (d1.Value() > 0) { sign = 1; } if (!d0.Contains(sign)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(sign), trail); } } return(true); } if (d0.Size() == 1) { // Sign(v1) = v0 int sign = d0.Value(); if (sign < 0) { if (d1.Maximum() >= 0) { d1 = d1.CapInterval(IntDomain.MinValue, -1); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } if (sign == 0) { if (!d1.Contains(0)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(0), trail); } } return(true); } if (sign > 0) { if (d1.Minimum() <= 0) { d1 = d1.CapInterval(1, IntDomain.MaxValue); if (d1.Empty) { return(false); } if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } return(false); } // v0 = Sign(v1) if (!(-1 <= d0.Minimum() && d0.Maximum() <= 1)) { d0 = d0.CapInterval(-1, 1); } if (d1.Minimum() >= 0) { d0 = d0.Delete(-1); } if (!d1.Contains(0)) { d0 = d0.Delete(0); } if (d1.Maximum() <= 0) { d0 = d0.Delete(1); } // Sign(v1) = v0 if (!d0.Contains(-1)) { if (d1.Minimum() < 0) { d1 = d1.CapInterval(0, IntDomain.MaxValue); } } if (!d0.Contains(0)) { d1 = d1.Delete(0); } if (!d0.Contains(1)) { if (d1.Maximum() > 0) { d1 = d1.CapInterval(IntDomain.MinValue, 0); } } if (d0.Empty) { return(false); } if (d1.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }
private static bool SatisfyABS(Variable v0, Variable v1, Trail trail) { var d0 = (IntDomain)v0.Domain; var d1 = (IntDomain)v1.Domain; if (d1.Size() == 1) { // v0 = Abs(v1) int value = Math.Abs(d1.Value()); if (!d0.Contains(value)) { return(false); } if (d0.Size() > 1) { if (trail != null) { v0.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d0.Size() == 1) { // Abs(v1) = v0 int value = d0.Value(); if (value < 0) { return(false); } if (value == 0) { if (!d1.Contains(value)) { return(false); } if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d1.Contains(value) && d1.Contains(-value)) { if (d1.Size() > 2) { value = Math.Abs(value); d1 = new IntDomain(-value, value); d1 = d1.Delete(-value + 1, value - 1); if (trail != null) { v1.UpdateDomain(d1, trail); } } return(true); } if (d1.Contains(value)) { if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(value), trail); } } return(true); } if (d1.Contains(-value)) { if (d1.Size() > 1) { if (trail != null) { v1.UpdateDomain(new IntDomain(-value), trail); } } return(true); } return(false); } int min; int max; // v0 = Abs(v1) if (d1.Minimum() >= 0) { min = d1.Minimum(); max = d1.Maximum(); } else if (d1.Maximum() <= 0) { min = -d1.Maximum(); max = -d1.Minimum(); } else { min = 0; max = Math.Max(-d1.Minimum(), d1.Maximum()); } d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } if (trail != null) { v0.UpdateDomain(d0, trail); } // Abs(v1) = v0 min = d0.Minimum(); max = d0.Maximum(); d1 = d1.CapInterval(-max, max); if (d1.Empty) { return(false); } if (min > 0) { d1 = d1.Delete(-min + 1, min - 1); } if (trail != null) { v1.UpdateDomain(d1, trail); } return(true); }
protected override internal bool Satisfy(Trail trail) { int n = v.Length; // limit the domain of v1 to 0..n-1 var d1 = (IntDomain)v1.Domain; d1 = d1.CapInterval(0, n - 1); if (d1.Empty) { return(false); } // get the possible range of v[i] as Min..Max int min = IntDomain.MaxValue; int max = IntDomain.MinValue; for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain)v[i].Domain; min = Math.Min(min, d.Minimum()); max = Math.Max(max, d.Maximum()); } } if (min > max) { return(false); } // limit the domain of v0 to Min..Max var d0 = (IntDomain)v0.Domain; d0 = d0.CapInterval(min, max); if (d0.Empty) { return(false); } // Delete impossible indices from v1 for (int i = 0; i < n; i++) { if (d1.Contains(i)) { var d = (IntDomain)v[i].Domain; if (d0.CapInterval(d.Minimum(), d.Maximum()).Empty) { d1 = d1.Delete(i); } } } if (d1.Empty) { return(false); } // propagate v0 to v[v1] when v1 is determined if (d1.Size() == 1) { int i = d1.Value(); var d = (IntDomain)v[i].Domain; d0 = (IntDomain)d.Cap(d0); if (d0.Empty) { return(false); } if (trail != null) { v[i].UpdateDomain(d0, trail); } } if (trail != null) { v0.UpdateDomain(d0, trail); v1.UpdateDomain(d1, trail); } return(true); }