Пример #1
0
            public static IDictionary <TVar, Sequence <TInterval> > GreaterEqualThanZero <TEnv, TVar, TExpr, TInterval>
                (TExpr expr, IExpressionDecoder <TVar, TExpr> decoder, TEnv env)
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                var result   = new Dictionary <TVar, Sequence <TInterval> > ();
                var variable = decoder.UnderlyingVariable(expr);

                AddToResult(result, variable, env.Eval(expr).Meet(env.Context.Positive));

                if (!decoder.IsVariable(expr))
                {
                    Polynomial <TVar, TExpr> zeroPoly;                    // poly(0)
                    if (!Polynomial <TVar, TExpr> .TryToPolynomial(new[] { Monomial <TVar> .From(Rational.Zero) }, out zeroPoly))
                    {
                        throw new AbstractInterpretationException(
                                  "It can never be the case that the conversion of a list of monomials into a polynomial fails.");
                    }

                    Polynomial <TVar, TExpr> exprPoly;                    // poly(expr)
                    Polynomial <TVar, TExpr> fullPoly;                    // '0 <= poly(expr)' polynome
                    if (Polynomial <TVar, TExpr> .TryBuildFrom(expr, decoder, out exprPoly) &&
                        Polynomial <TVar, TExpr> .TryToPolynomial(ExpressionOperator.LessEqualThan, zeroPoly, exprPoly, out fullPoly) &&
                        fullPoly.IsIntervalForm)
                    {
                        var  k = fullPoly.Left[0].Coeff;                        // k != 0
                        TVar x;
                        fullPoly.Left[0].IsSingleVariable(out x);

                        Rational constraint;
                        if (Rational.TryDivide(fullPoly.Right[0].Coeff, k, out constraint))
                        {
                            TInterval interval;
                            if (k > 0L)                             // +x <= constraint
                            {
                                interval = env.Eval(x).Meet(env.Context.For(Rational.MinusInfinity, constraint));
                            }
                            else                             // -x <= -constraint ==> x >= constraint
                            {
                                interval = env.Eval(x).Meet(env.Context.For(constraint, Rational.PlusInfinity));
                            }

                            AddToResult(result, x, interval);
                        }
                    }
                }
                return(result);
            }
Пример #2
0
            /// <summary>
            /// Get constraints for variables from polynome in form 'a*x &lt;= k'
            /// </summary>
            /// <param name="poly">Polynome in canonical form. Two monomes involved. </param>
            static IDictionary <TVar, Sequence <TInterval> > TestTrueLessEqualThan_AxLtK <TEnv, TVar, TExpr, TInterval>
                (Polynomial <TVar, TExpr> poly, TEnv env, IDictionary <TVar, Sequence <TInterval> > result, out bool isBottom)
                where TEnv : IIntervalEnvironment <TVar, TExpr, TInterval, Rational>
                where TVar : IEquatable <TVar>
                where TInterval : IntervalBase <TInterval, Rational>
            {
                isBottom = false;

                var ax = poly.Left[0];
                var k  = poly.Right[1];

                if (ax.IsConstant)
                {
                    if (ax.Coeff >= k.Coeff)
                    {
                        isBottom = true;
                        return(result);
                    }
                }
                else
                {
                    TVar x;
                    ax.IsSingleVariable(out x);
                    Rational div;
                    if (Rational.TryDivide(k.Coeff, ax.Coeff, out div))
                    {
                        var intv = env.Eval(x);

                        var boundByDivPlus = !div.IsInteger
                                                                             ? env.Context.For(div.NextInt32, Rational.PlusInfinity)
                                                                             : env.Context.For(div + 1L, Rational.PlusInfinity);
                        var boundByDivMinus = !div.IsInteger
                                                                              ? env.Context.For(Rational.MinusInfinity, div.NextInt32 - 1L)
                                                                              : env.Context.For(Rational.MinusInfinity, div - 1L);
                        var refined = intv.Meet(ax.Coeff.Sign < 1 ? boundByDivPlus : boundByDivMinus);

                        if (refined.IsBottom)
                        {
                            isBottom = true;
                            return(result);
                        }

                        AddToResult(result, x, refined);
                    }
                }
                return(result);
            }