private IntDomain Divide(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) { return(IntDomain.EmptyDomain); } } if (d2.Contains(0)) { return(d0); } if (d2.Maximum() < 0 || 0 < d2.Minimum()) { var x = new[] { d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum() }; d0 = d0.CapInterval(Min(x), Max(x)); } else { var x = new[] { d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum(), d1.Minimum(), d1.Maximum(), -d1.Minimum(), -d1.Maximum() }; d0 = d0.CapInterval(Min(x), Max(x)); } return(d0); }
/// <summary> /// Captilizes interval /// </summary> /// <param name="low"> /// The low.value /// </param> /// <param name="high"> /// The high.value /// </param> /// <returns> /// a modified domain /// </returns> public virtual IntDomain CapInterval(int low, int high) { IntDomain d = this; if (MinValue < low) { d = d.Delete(MinValue, low - 1); } if (high < MaxValue) { d = d.Delete(high + 1, MaxValue); } return(d); }
private IntDomain Multiply(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0) && !d2.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) { return(IntDomain.EmptyDomain); } } var x = new[] { ToInt(d1.Minimum() * (long)d2.Minimum()), ToInt(d1.Minimum() * (long)d2.Maximum()), ToInt(d1.Maximum() * (long)d2.Minimum()), ToInt(d1.Maximum() * (long)d2.Maximum()) }; d0 = d0.CapInterval(Min(x), Max(x)); return(d0); }
private static IntDomain Multiply(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0) && !d2.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) return IntDomain.emptyDomain; } var x = new[] { ToInt(d1.Minimum() * (long) d2.Minimum()), ToInt(d1.Minimum() * (long) d2.Maximum()), ToInt(d1.Maximum() * (long) d2.Minimum()), ToInt(d1.Maximum() * (long) d2.Maximum()) }; d0 = d0.CapInterval(Min(x), Max(x)); return d0; }
private static IntDomain Divide(IntDomain d0, IntDomain d1, IntDomain d2) { if (!d1.Contains(0)) { d0 = d0.Delete(0); if (d0.Empty) return IntDomain.emptyDomain; } if (d2.Contains(0)) { return d0; } if (d2.Maximum() < 0 || 0 < d2.Minimum()) { var x = new[]{d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum()}; d0 = d0.CapInterval(Min(x), Max(x)); } else { var x = new[]{d1.Minimum() / d2.Minimum(), d1.Maximum() / d2.Minimum(), d1.Minimum() / d2.Maximum(), d1.Maximum() / d2.Maximum(), d1.Minimum(), d1.Maximum(), - d1.Minimum(), - d1.Maximum()}; d0 = d0.CapInterval(Min(x), Max(x)); } return d0; }
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 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); }