private object EvaluateVariable(Variable v)
            {
                if (!_ivStack.Contains(v))
                {
                    throw new BreakEvaluationException();
                }
                IVRange range = _iva._ivLoopRange[v];

                return(range);
            }
        /// <summary>
        /// Retrieves the value range constraint for a specific variable.
        /// </summary>
        /// <param name="v">variable to query</param>
        /// <param name="minValue">minimum value</param>
        /// <param name="maxValue">maximum value</param>
        /// <exception cref="ArgumentException">if no value range constraint exists for the specified variable</exception>
        public void GetRange(Variable v, out long minValue, out long maxValue)
        {
            if (!IsConstrained(v))
            {
                throw new ArgumentException("no value range constraint found", "v");
            }
            IVRange range = _ivLoopRange[v];

            minValue = range.MinValue;
            maxValue = range.MaxValue;
        }
            public void AcceptLoopBlock(LoopBlock stmt)
            {
                if (stmt.Initializer != null &&
                    stmt.CounterStart != null &&
                    stmt.CounterStop != null &&
                    stmt.CounterStep != null)
                {
                    if (/*stmt.CounterStart.IsConst(_ecr) &&
                         * stmt.CounterStop.IsConst(_ecr) &&*/
                        stmt.CounterStep.IsConst(_ecr))
                    {
                        try
                        {
                            Expression minExpr, maxExpr;
                            switch (stmt.CounterDirection)
                            {
                            case LoopBlock.ECounterDirection.Increment:
                                minExpr = stmt.CounterStart;
                                maxExpr = stmt.CounterStop + stmt.CounterStep;
                                if (stmt.CounterLimitKind == LoopBlock.ELimitKind.ExcludingStopValue)
                                {
                                    maxExpr -= LiteralReference.CreateConstant((long)1);
                                }
                                break;

                            case LoopBlock.ECounterDirection.Decrement:
                                maxExpr = stmt.CounterStart;
                                minExpr = stmt.CounterStop - stmt.CounterStep;
                                if (stmt.CounterLimitKind == LoopBlock.ELimitKind.ExcludingStopValue)
                                {
                                    minExpr += LiteralReference.CreateConstant((long)1);
                                }
                                break;

                            default:
                                throw new NotImplementedException();
                            }

                            object  min       = minExpr.Eval(_eval);
                            object  max       = maxExpr.Eval(_eval);
                            IVRange minR      = IVRange.ToRange(min);
                            IVRange maxR      = IVRange.ToRange(max);
                            IVRange loopRange = IVRange.Max(minR, maxR);

                            if (_iva._ivLoopRange.ContainsKey(stmt.CounterVariable))
                            {
                                _iva._ivLoopRange[stmt.CounterVariable] =
                                    IVRange.Max(_iva._ivLoopRange[stmt.CounterVariable], loopRange);
                            }
                            else
                            {
                                _iva._ivLoopRange[stmt.CounterVariable] = loopRange;
                            }
                            _iva._inductionVars.Add(stmt.CounterVariable, stmt);
                            _ivStack.Push(stmt.CounterVariable);
                            stmt.Body.Accept(this);
                            if (stmt.Trailer != null)
                            {
                                stmt.Trailer.Accept(this);
                            }
                            _ivStack.Pop();
                            return;
                        }
                        catch (BreakEvaluationException)
                        {
                        }
                        catch (InvalidCastException)
                        {
                        }
                        catch (InvalidOperationException)
                        {
                        }
                    }
                    _iva._unconstrainedVars.Add(stmt.CounterVariable);
                }

                stmt.Body.Accept(this);
                if (stmt.Trailer != null)
                {
                    stmt.Trailer.Accept(this);
                }
            }
 public static IVRange Max(IVRange r1, IVRange r2)
 {
     return(new IVRange(
                Math.Min(r1.MinValue, r2.MinValue),
                Math.Max(r1.MaxValue, r2.MaxValue)));
 }