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); }
/// <summary> /// Get constraints for variables from polynome in form 'a*x <= 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); }