コード例 #1
0
ファイル: Program.cs プロジェクト: kikoanis/CSharpCream
        static void Main(string[] args)
        {
            Network net = new Network();

            IntVariable[] A = new IntVariable[6];
            for (int j=0; j< 6; j++)
            {
                IntDomain d = new IntDomain(1, 9);
                A[j] = new IntVariable(net);
                A[j].Domain = d;
                Trail trail = new Trail();
            }
            ((A[4].Multiply(10).Add(A[5])).Multiply(A[0])).Add(
            ((A[1].Multiply(10).Add(A[2])).Multiply(A[3]))).Equals(
                (A[1].Multiply(10).Add(A[2])).Multiply(A[4].Multiply(10).Add(A[5])));
            new NotEquals(net, A);
            Solver solver = new DefaultSolver(net);
            int i = 0;
            for (solver.Start(); solver.WaitNext(); solver.Resume())
            {
                Solution solution = solver.Solution;
                Console.Out.WriteLine();
                Console.Out.WriteLine(solution.GetIntValue(A[0]) + "    " + solution.GetIntValue(A[3]));
                Console.Out.WriteLine("-- + -- = 1");
                Console.Out.WriteLine(solution.GetIntValue(A[1])+""+solution.GetIntValue(A[2])+"   "+
                                      solution.GetIntValue(A[4]) + solution.GetIntValue(A[5]));
                Console.Out.WriteLine("=========");
                i++;
            }
            Console.Out.WriteLine("There are {0} solutions",i);

            solver.Stop();
            Console.In.ReadLine();
            //------------------------------------------------------------------------------------------
        }
コード例 #2
0
ファイル: Serialized.cs プロジェクト: samplet/HalfAndHalf
 private bool SatisfySequential(Trail trail)
 {
     if (_order == null)
         return true;
     for (int k = 0; k < _order.Length - 1; k++)
     {
         int i = _order[k];
         int j = _order[k + 1];
         var d0 = (IntDomain) _v[i].Domain;
         var d1 = (IntDomain) _v[j].Domain;
         int diffMin = d1.Maximum() - _l[i] + 1;
         int diffMax = d0.Minimum() + _l[i] - 1;
         d0 = d0.Delete(diffMin, IntDomain.MaxValue);
         if (d0.Empty)
             return false;
         d1 = d1.Delete(IntDomain.MinValue, diffMax);
         if (d1.Empty)
             return false;
         if (trail != null)
         {
             _v[i].UpdateDomain(d0, trail);
             _v[j].UpdateDomain(d1, trail);
         }
     }
     return true;
 }
コード例 #3
0
        //public int getMostSoftSatisfiedDomain()
        //{
        //    Domain d = v[0].Domain;
        //    if (CType == ConstraintTypes.Soft)
        //    {
        //        for (int i = 1; i < v.Length; i++)
        //        {
        //            d = d.Cap(v[i].Domain);
        //            if (d.EmptyDomain)
        //                return -1;
        //        }
        //    }
        //    return ((IntDomain) d).Min();
        //}

        protected internal override bool Satisfy(Trail trail)
        {
            Domain d = v[0].Domain;

            for (int i = 1; i < v.Length; i++)
            {
                d = d.Cap(v[i].Domain);
                if (d.Empty)
                {
                    return(false);
                }
            }
            if (trail != null)
            {
                for (int i = 0; i < v.Length; i++)
                {
                    v[i].UpdateDomain(d, trail);
                }
            }
            return(true);
        }
コード例 #4
0
        protected internal override bool Satisfy(Trail trail)
        {
            switch (arith)
            {
            case Add:
                return(SatisfyADD(v[0], v[1], v[2], trail));

            case Subtract:
                return(SatisfyADD(v[1], v[0], v[2], trail));

            case MULTIPLY:
                return(SatisfyMULTIPLY(v[0], v[1], v[2], trail));

            case MAX:
                return(SatisfyMAX(v[0], v[1], v[2], trail));

            case MIN:
                return(SatisfyMIN(v[0], v[1], v[2], trail));
            }
            return(false);
        }
コード例 #5
0
ファイル: Sequential.cs プロジェクト: samplet/HalfAndHalf
 protected internal override bool Satisfy(Trail trail)
 {
     for (int i = 0; i < _v.Length - 1; i++)
     {
         int j = i + 1;
         var d0 = (IntDomain) _v[i].Domain;
         var d1 = (IntDomain) _v[j].Domain;
         int diffMin = d1.Maximum() - _l[i] + 1;
         int diffMax = d0.Minimum() + _l[i] - 1;
         d0 = d0.Delete(diffMin, IntDomain.MaxValue);
         if (d0.Empty)
             return false;
         d1 = d1.Delete(IntDomain.MinValue, diffMax);
         if (d1.Empty)
             return false;
         if (trail != null)
         {
             _v[i].UpdateDomain(d0, trail);
             _v[j].UpdateDomain(d1, trail);
         }
     }
     return true;
 }
コード例 #6
0
ファイル: NotEquals.cs プロジェクト: samplet/HalfAndHalf
 protected internal override bool Satisfy(Trail trail)
 {
     for (int i = 0; i < _v.Length; i++)
     {
         Domain d = _v[i].Domain;
         if (d.Size() != 1)
             continue;
         Object elem = d.Element();
         for (int j = 0; j < _v.Length; j++)
         {
             if (i == j)
                 continue;
             Domain d1 = _v[j].Domain.Delete(elem);
             if (d1.Empty)
                 return false;
             if (trail != null)
             {
                 _v[j].UpdateDomain(d1, trail);
             }
         }
     }
     return true;
 }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
ファイル: IntArith.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #10
0
ファイル: IntArith.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #11
0
        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);
        }
コード例 #12
0
ファイル: DefaultSolver.cs プロジェクト: kikoanis/CSharpCream
 /// <summary>
 /// Run method
 /// </summary>
 public override void Run()
 {
     ClearBest();
     trail = new Trail();
     Solve(0);
     trail.Undo(0);
     Fail();
 }
コード例 #13
0
ファイル: Serialized.cs プロジェクト: samplet/HalfAndHalf
 private bool SatisfySerialized(Trail trail)
 {
     for (int i = 0; i < _v.Length; i++)
     {
         for (int j = 0; j < _v.Length; j++)
         {
             if (i == j)
                 continue;
             var d0 = (IntDomain) _v[i].Domain;
             var d1 = (IntDomain) _v[j].Domain;
             int diffMin = d1.Maximum() - _l[i] + 1;
             int diffMax = d1.Minimum() + _l[j] - 1;
             if (diffMin <= diffMax)
             {
                 d0 = d0.Delete(diffMin, diffMax);
                 if (d0.Empty)
                     return false;
                 if (trail != null)
                 {
                     _v[i].UpdateDomain(d0, trail);
                 }
             }
         }
     }
     return true;
 }
コード例 #14
0
ファイル: Element.cs プロジェクト: samplet/HalfAndHalf
 protected internal override 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;
 }
コード例 #15
0
ファイル: IntFunc.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #16
0
ファイル: IntFunc.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #17
0
ファイル: IntFunc.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #18
0
ファイル: IntFunc.cs プロジェクト: kikoanis/CSharpCream
        protected internal override bool Satisfy(Trail trail)
        {
            switch (_arith)
            {
                case Negate:
                    return SatisfyNEGATE(_v[0], _v[1], trail);

                case Abs:
                    return SatisfyABS(_v[0], _v[1], trail);

                case Sign:
                    return SatisfySIGN(_v[0], _v[1], trail);
                }
            return false;
        }
コード例 #19
0
ファイル: Equals.cs プロジェクト: kikoanis/CSharpCream
 //public int getMostSoftSatisfiedDomain()
 //{
 //    Domain d = v[0].Domain;
 //    if (CType == ConstraintTypes.Soft)
 //    {
 //        for (int i = 1; i < v.Length; i++)
 //        {
 //            d = d.Cap(v[i].Domain);
 //            if (d.EmptyDomain)
 //                return -1;
 //        }
 //    }
 //    return ((IntDomain) d).Min();
 //}
 protected internal override bool Satisfy(Trail trail)
 {
     Domain d = _v[0].Domain;
     for (int i = 1; i < _v.Length; i++)
     {
         d = d.Cap(_v[i].Domain);
         if (d.Empty)
             return false;
     }
     if (trail != null)
     {
         foreach (Variable t in _v)
         {
             t.UpdateDomain(d, trail);
         }
     }
     return true;
 }
コード例 #20
0
ファイル: Serialized.cs プロジェクト: samplet/HalfAndHalf
 protected internal override bool Satisfy(Trail trail)
 {
     if (!SatisfySequential(trail))
         return false;
     return SatisfySerialized(trail);
 }
コード例 #21
0
ファイル: Relation.cs プロジェクト: kikoanis/CSharpCream
 protected internal override 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;
 }
コード例 #22
0
ファイル: Variable.cs プロジェクト: kikoanis/CSharpCream
 /// <summary>
 /// Updates the domain of the current variable with the parameter domain d after
 /// pushing the Trail trial
 /// </summary>
 /// <param name="d">the domain to be updated with</param>
 /// <param name="trail">the trail to be pushed</param>
 public virtual void UpdateDomain(Domain d, Trail trail)
 {
     if (_domain == null || !_domain.Equals(d))
     {
         trail.Push(this);
         _domain = d;
         _modified = true;
         if (_watch)
         {
             Console.Out.WriteLine(this + " = " + _domain);
         }
     }
 }
コード例 #23
0
ファイル: IntComparison.cs プロジェクト: samplet/HalfAndHalf
 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;
 }
コード例 #24
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);
        }
コード例 #25
0
ファイル: IntComparison.cs プロジェクト: samplet/HalfAndHalf
        protected internal override bool Satisfy(Trail trail)
        {
            switch (_comparison)
            {

                case Le:
                    return SatisfyLE(_v[0], _v[1], trail);

                case Lt:
                    return SatisfyLT(_v[0], _v[1], trail);

                case Ge:
                    return SatisfyLE(_v[1], _v[0], trail);

                case Gt:
                    return SatisfyLT(_v[1], _v[0], trail);
            }
            return false;
        }
コード例 #26
0
ファイル: Constraint.cs プロジェクト: samplet/HalfAndHalf
 protected internal abstract bool Satisfy(Trail trail);
コード例 #27
0
ファイル: IntArith.cs プロジェクト: kikoanis/CSharpCream
        protected internal override bool Satisfy(Trail trail)
        {
            switch (_arith)
            {

                case Add:
                    return SatisfyAdd(_v[0], _v[1], _v[2], trail);

                case Subtract:
                    return SatisfyAdd(_v[1], _v[0], _v[2], trail);

                case MULTIPLY:
                    return SatisfyMULTIPLY(_v[0], _v[1], _v[2], trail);

                case MAX:
                    return SatisfyMAX(_v[0], _v[1], _v[2], trail);

                case MIN:
                    return SatisfyMIN(_v[0], _v[1], _v[2], trail);
                }
            return false;
        }
コード例 #28
0
        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);
        }
コード例 #29
0
ファイル: IntArith.cs プロジェクト: kikoanis/CSharpCream
        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;
        }
コード例 #30
0
        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);
        }
コード例 #31
0
        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);
        }
コード例 #32
0
 protected internal abstract bool Satisfy(Trail trail);