Ejemplo n.º 1
0
        /// <summary>
        /// Adds "le" to "this".  Afterwards, "le" should not be used, because it will have been destroyed.
        /// </summary>
        /// <param name="le"></param>
        public void Add(LinearExpr /*!*/ le) /* throws ArithmeticException */
        {
            Contract.Requires(le != null);
            Contract.Requires(le != this);
            checked {
                constant += le.constant;
            }
            le.constant = BigNum.FromInt(-70029); // "le" should no longer be used; assign it a strange value so that misuse is perhaps more easily detected

            // optimization:
            if (le.terms == null)
            {
                return;
            }
            else if (terms == null)
            {
                terms    = le.terms;
                le.terms = null;
                return;
            }

            // merge the two term lists
            // Use a nested loop, which is quadratic in time complexity, but we hope the lists will be small
            Term newTerms = null;

            while (le.terms != null)
            {
                // take off next term from "le"
                Term t = le.terms;
                le.terms = t.next;
                t.next   = null;

                for (Term u = terms; u != null; u = u.next)
                {
                    if (u.var == t.var)
                    {
                        checked {
                            u.coeff += t.coeff;
                        }
                        goto NextOuter;
                    }
                }
                t.next   = newTerms;
                newTerms = t;

NextOuter:
                ;
            }

            // finally, include all non-0 terms
            while (terms != null)
            {
                // take off next term from "this"
                Term t = terms;
                terms = t.next;

                if (!t.coeff.IsZero)
                {
                    t.next   = newTerms;
                    newTerms = t;
                }
            }
            terms = newTerms;
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Builds a linear expression from "e", if possible; returns null if not possible.
        /// </summary>
        /// <param name="e"></param>
        /// <returns></returns>
        public static /*maybe null*/ LinearExpr AsExpr(IExpr /*!*/ e) /* throws ArithmeticException */
        {
            Contract.Requires(e != null);
            if (e is IVariable)
            {
                // Note, without a type for the variable, we don't know if the identifier is intended to hold an integer value.
                // However, it seems that no harm can be caused by here treating the identifier as if it held an
                // integer value, because other parts of this method will reject the expression as a linear expression
                // if non-numeric operations other than equality are applied to the identifier.
                return(new LinearExpr((IVariable)e));
            }
            else if (e is IFunApp)
            {
                IFunApp /*!*/ funapp = (IFunApp)e;
                Contract.Assert(funapp != null);
                IFunctionSymbol /*!*/ s = funapp.FunctionSymbol;
                Contract.Assert(s != null);

                if (s is IntSymbol)
                {
                    return(new LinearExpr(((IntSymbol)s).Value));
                }
                else if (s.Equals(Int.Negate))
                {
                    Contract.Assert(funapp.Arguments.Count == 1);
                    LinearExpr le = AsExpr((IExpr /*!*/)cce.NonNull(funapp.Arguments[0]));
                    if (le != null)
                    {
                        le.Negate();
                        return(le);
                    }
                }
                else if (s.Equals(Int.Add) || s.Equals(Int.Sub) || s.Equals(Int.Mul))
                {
                    Contract.Assert(funapp.Arguments.Count == 2);
                    IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[0]);
                    IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[1]);
                    LinearExpr  le0  = AsExpr(arg0);
                    if (le0 == null)
                    {
                        return(null);
                    }
                    LinearExpr le1 = AsExpr(arg1);
                    if (le1 == null)
                    {
                        return(null);
                    }

                    if (s.Equals(Int.Add))
                    {
                        le0.Add(le1);
                        return(le0);
                    }
                    else if (s.Equals(Int.Sub))
                    {
                        le1.Negate();
                        le0.Add(le1);
                        return(le0);
                    }
                    else if (s.Equals(Int.Mul))
                    {
                        BigNum x;
                        if (le0.AsConstant(out x))
                        {
                            le1.Multiply(x);
                            return(le1);
                        }
                        else if (le1.AsConstant(out x))
                        {
                            le0.Multiply(x);
                            return(le0);
                        }
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 3
0
    /// <summary>
    /// Adds "le" to "this".  Afterwards, "le" should not be used, because it will have been destroyed.
    /// </summary>
    /// <param name="le"></param>
    public void Add(LinearExpr/*!*/ le) /* throws ArithmeticException */
        {
      Contract.Requires(le != null);
      Contract.Requires(le != this);
      checked {
        constant += le.constant;
      }
      le.constant = BigNum.FromInt(-70029);  // "le" should no longer be used; assign it a strange value so that misuse is perhaps more easily detected

      // optimization:
      if (le.terms == null) {
        return;
      } else if (terms == null) {
        terms = le.terms;
        le.terms = null;
        return;
      }

      // merge the two term lists
      // Use a nested loop, which is quadratic in time complexity, but we hope the lists will be small
      Term newTerms = null;
      while (le.terms != null) {
        // take off next term from "le"
        Term t = le.terms;
        le.terms = t.next;
        t.next = null;

        for (Term u = terms; u != null; u = u.next) {
          if (u.var == t.var) {
            checked {
              u.coeff += t.coeff;
            }
            goto NextOuter;
          }
        }
        t.next = newTerms;
        newTerms = t;

      NextOuter:
        ;
      }

      // finally, include all non-0 terms
      while (terms != null) {
        // take off next term from "this"
        Term t = terms;
        terms = t.next;

        if (!t.coeff.IsZero) {
          t.next = newTerms;
          newTerms = t;
        }
      }
      terms = newTerms;
    }
Ejemplo n.º 4
0
        static /*maybe null*/ LinearCondition GetCond(IExpr e, bool positive) /* throws ArithmeticException */
        {
            IFunApp funapp = e as IFunApp;

            if (funapp == null)
            {
                return(null);
            }
            IFunctionSymbol /*!*/ s = funapp.FunctionSymbol;

            Contract.Assert(s != null);
            if ((positive && s.Equals(Prop.False)) ||
                (!positive && s.Equals(Prop.True)))
            {
                return(new LCBottom());
            }
            else if (s.Equals(Prop.Not))
            {
                Contract.Assert(funapp.Arguments.Count == 1);
                return(GetCond((IExpr /*!*/)cce.NonNull(funapp.Arguments[0]), !positive));
            }
            else if (funapp.Arguments.Count == 2)
            {
                IExpr /*!*/ arg0 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[0]);
                IExpr /*!*/ arg1 = (IExpr /*!*/)cce.NonNull(funapp.Arguments[1]);
                LinearExpr  le0  = AsExpr(arg0);
                if (le0 == null)
                {
                    return(null);
                }
                LinearExpr le1 = AsExpr(arg1);
                if (le1 == null)
                {
                    return(null);
                }

                LinearConstraint constraint = null;
                bool             sense      = true;
                if ((positive && s.Equals(Int.Less)) || (!positive && s.Equals(Int.AtLeast)))
                {
                    constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ONE);
                }
                else if ((positive && s.Equals(Int.AtMost)) || (!positive && s.Equals(Int.Greater)))
                {
                    constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO);
                }
                else if ((positive && s.Equals(Int.AtLeast)) || (!positive && s.Equals(Int.Less)))
                {
                    constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ZERO);
                }
                else if ((positive && s.Equals(Int.Greater)) || (!positive && s.Equals(Int.AtMost)))
                {
                    constraint = MakeConstraint(le1, le0, LinearConstraint.ConstraintRelation.LE, BigNum.ONE);
                }
                else if (s.Equals(Int.Eq))
                {
                    constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO);
                    sense      = positive;
                }
                else if (s.Equals(Int.Neq))
                {
                    constraint = MakeConstraint(le0, le1, LinearConstraint.ConstraintRelation.EQ, BigNum.ZERO);
                    sense      = !positive;
                }
                if (constraint != null)
                {
                    if (constraint.coefficients.Count != 0)
                    {
                        return(new LinearConditionLiteral(sense, constraint));
                    }
                    else if (constraint.IsConstantSatisfiable())
                    {
                        return(null);
                    }
                    else
                    {
                        return(new LCBottom());
                    }
                }
            }
            return(null);
        }
Ejemplo n.º 5
0
 public static LinearConstraint MakeConstraint(LinearExpr/*!*/ le0, LinearExpr/*!*/ le1,
     LinearConstraint.ConstraintRelation rel, BigNum constantOffset) /* throws ArithmeticException */
 {
   Contract.Requires(le0 != null);
   Contract.Requires(le1 != null);
   le1.Negate();
   le0.Add(le1);
   le0.AddConstant(constantOffset);
   return le0.ToConstraint(rel);
 }