コード例 #1
0
 protected override Expression VisitMethodCall(MethodCallExpression m)
 {
     if (m.Object != null && m.Object.NodeType == ExpressionType.Parameter)
     {
         var p = (ParameterExpression)m.Object;
         if (_paramWhere.Contains(p))
         {
             if (m.Method.Name != "get_Item" || m.Arguments[0].NodeType != ExpressionType.Constant)
             {
                 _nonConstant = true;
                 return(m);
             }
             var paramVar = _paramVar[p.Name];
             var index    = (int)((ConstantExpression)m.Arguments[0]).Value;
             if (index < 0 || index >= paramVar.ListCount)
             {
                 _indexOutOfLength = true;
                 return(m);
             }
             var kvp = IntExt.CreateLong(paramVar.Index, index);
             if (!_paramId.Contains(kvp))
             {
                 _paramId.Add(kvp);
             }
             return(makeListParam(_param, _methods, kvp, m.Type));
         }
     }
     return(base.VisitMethodCall(m));
 }
コード例 #2
0
        bool tryAppendAllDifferent(ReadOnlyCollection <Expression> exps)
        {
            var list = new HashSet <long>();

            foreach (var exp in exps)
            {
                switch (exp.NodeType)
                {
                case ExpressionType.Call:
                    var m = (MethodCallExpression)exp;
                    if (m.Method.Name == "get_Item" && m.Object.NodeType == ExpressionType.Parameter && m.Arguments[0].NodeType == ExpressionType.Constant)
                    {
                        list.Add(IntExt.CreateLong(_paramVar[((ParameterExpression)m.Object).Name].Index, (int)((ConstantExpression)m.Arguments[0]).Value));
                    }
                    else
                    {
                        return(false);
                    }
                    break;

                case ExpressionType.Parameter:
                    list.Add(IntExt.CreateLong(0, _paramVar[((ParameterExpression)exp).Name].Index));
                    break;

                default:
                    return(false);
                }
            }
            _exp = Expression.Call(_exp, "AppendAllDifferent", null, Expression.Constant(list));
            return(true);
        }
コード例 #3
0
 protected override Expression VisitParameter(ParameterExpression p)
 {
     if (_paramWhere.Contains(p) && !_paramVar[p.Name].IsList)
     {
         var kvp = IntExt.CreateLong(0, _paramVar[p.Name].Index);
         if (!_paramId.Contains(kvp))
         {
             _paramId.Add(kvp);
         }
         return(makeVarParam(_param, _methods, kvp.GetLowInt(), p.Type));
     }
     return(p);
 }
コード例 #4
0
        //public methods
        public virtual IEnumerable <List <ReadOnlyCollection <T> > > LookAhead()
        {
            if (_noSolution)
            {
                return(Enumerable.Empty <List <ReadOnlyCollection <T> > >());
            }

            var data = _variables.Select(a =>
                                         a.Select(b => b.ToList()).ToList()
                                         ).ToList();

            return(lookAhead(
                       data,
                       _variables.SelectMany((a, i) =>
                                             a.Select((b, j) => IntExt.CreateLong(i, j))
                                             ).ToArray(),
                       new HashSet <long>()
                       ).Select(s =>
                                s.GroupBy(a => a.Item1.GetHighInt()).OrderBy(a => a.Key).Select(a =>
                                                                                                a.OrderBy(b => b.Item1.GetLowInt()).Select(b => b.Item2).ToList().AsReadOnly()
                                                                                                ).ToList()
                                ));
        }
コード例 #5
0
        //local methods
        IEnumerable <IEnumerable <Tuple <long, T> > > lookAhead(List <List <List <T> > > data, long[] unsolved, HashSet <long> solved)
        {
            //all solved, return empty
            if (unsolved.Length == 0)
            {
                yield return(Tuple.Create(IntExt.CreateLong(0, _variables[0].Count), default(T)).ToEnumerable());

                yield break;
            }

            //do on first time
            if (solved.Count == 0)
            {
                var newData = data.Select(d => d.ToList()).ToList();
                foreach (var node in _nodeConstraints)
                {
                    filterData(newData, node.Key, node.Value.PredicateAll(), null);
                }
                unsolved = unsolved.OrderBy(x => getData(newData, x).Count).ToArray();
                data     = newData;
            }

            //pull out first unsolve
            var index      = unsolved[0];
            var candidate  = getData(data, index);
            var newUnsolve = new long[unsolved.Length - 1];

            Array.Copy(unsolved, 1, newUnsolve, 0, newUnsolve.Length);
            var newSolved = new HashSet <long>(solved)
            {
                index
            };

            //get predicate
            List <Tuple <HashSet <long>, Func <List <List <List <T> > >, bool> > > arc;

            _arcConstraints.TryGetValue(index, out arc);
            List <Tuple <HashSet <long>, Func <List <List <List <T> > >, bool> > > pair;

            _pairConstraints.TryGetValue(index, out pair);
            List <HashSet <long> > diff;

            _allDifferents.TryGetValue(index, out diff);

            foreach (var t in candidate)
            {
                //create new data set
                var newData = data.Select(d => d.ToList()).ToList();
                setData(newData, index, new List <T> {
                    t
                });

                //find minimum scope
                var minValue   = int.MaxValue;
                var minUnSolve = 0;

                //set occurrents
                List <Dictionary <T, int> > valueCheck = null;
                if (_occurrents.Count > 0)
                {
                    valueCheck = new List <Dictionary <T, int> >(_occurrents.Count);
                    for (var i = 0; i < _occurrents.Count; i++)
                    {
                        valueCheck.Add(new Dictionary <T, int>(tComparer));
                    }
                }

                //for each unsolve
                for (var j = 0; j < newUnsolve.Length; j++)
                {
                    var prediList = Enumerable.Empty <Func <List <List <List <T> > >, bool> >();
                    var k         = newUnsolve[j];

                    //apply predicate
                    if (diff != null)
                    {
                        prediList = diff.Where(a => a.Contains(k))
                                    .Take(1)
                                    .Select(a => new Func <List <List <List <T> > >, bool>(x => !tComparer.Equals(x[k.GetHighInt()][k.GetLowInt()][0], t)));
                    }
                    if (pair != null)
                    {
                        prediList = prediList.Concat(pair.Where(a => a.Item1.Contains(k))
                                                     .Take(1)
                                                     .Select(a => a.Item2));
                    }
                    if (arc != null)
                    {
                        prediList = prediList.Concat(arc.Where(a => a.Item1.All(b => b == k || newSolved.Contains(b)))
                                                     .Select(a => a.Item2));
                    }
                    var predicate = prediList.PredicateAll();

                    //if predicate is not empty
                    if (!Equals(predicate, emptyPredicate))
                    {
                        filterData(newData, k, predicate, val => setValueCheck(valueCheck, val, j, newUnsolve[j]));
                    }
                    else if (_occurrents.Count > 0)
                    {
                        var oldList = getData(newData, k);
                        foreach (var item in oldList)
                        {
                            setValueCheck(valueCheck, item, j, newUnsolve[j]);
                        }
                    }

                    //set minimum scope
                    if (j == 0 || getData(newData, k).Count < minValue)
                    {
                        minUnSolve = j;
                        minValue   = getData(newData, k).Count;
                    }
                }

                //apply occurents
                if (_occurrents.Count > 0)
                {
                    foreach (var c in valueCheck)
                    {
                        foreach (var kvp in c)
                        {
                            if (kvp.Value == -1)
                            {
                                continue;
                            }
                            var k = newUnsolve[kvp.Value];
                            setData(newData, k, new List <T> {
                                kvp.Key
                            });
                            if (minValue > 1)
                            {
                                minValue   = 1;
                                minUnSolve = kvp.Value;
                            }
                        }
                    }
                }

                //swop item based on minimum scope
                if (minUnSolve > 0)
                {
                    var tmp = newUnsolve[0];
                    newUnsolve[0]          = newUnsolve[minUnSolve];
                    newUnsolve[minUnSolve] = tmp;
                }

                //iterate next item
                foreach (var r in lookAhead(newData, newUnsolve, newSolved))
                {
                    yield return(Tuple.Create(index, t).ToEnumerable().Concat(r));
                }
            }
        }