예제 #1
0
 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);
 }
예제 #2
0
        /// <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);
        }
예제 #3
0
        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);
        }
예제 #4
0
 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;
 }
예제 #5
0
 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;
 }
예제 #6
0
        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;
        }
예제 #7
0
        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);
        }