/// <summary>
    /// Tests the example in section 3.4.3 of Cousot and Halbwachs.
    /// </summary>
    public static void RunValidationB() {
      IVariable/*!*/ X = new TestVariable("X");
      IVariable/*!*/ Y = new TestVariable("Y");
      IVariable/*!*/ Z = new TestVariable("Z");
      Contract.Assert(X != null);
      Contract.Assert(Y != null);
      Contract.Assert(Z != null);
      ArrayList /*LinearConstraint*/ cs = new ArrayList /*LinearConstraint*/ ();

      LinearConstraint c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE);
      c.SetCoefficient(X, Rational.MINUS_ONE);
      c.SetCoefficient(Y, Rational.ONE);
      c.SetCoefficient(Z, Rational.MINUS_ONE);
      c.rhs = Rational.ZERO;
      cs.Add(c);

      c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE);
      c.SetCoefficient(X, Rational.MINUS_ONE);
      c.rhs = Rational.MINUS_ONE;
      cs.Add(c);

      c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE);
      c.SetCoefficient(X, Rational.MINUS_ONE);
      c.SetCoefficient(Y, Rational.MINUS_ONE);
      c.SetCoefficient(Z, Rational.ONE);
      c.rhs = Rational.ZERO;
      cs.Add(c);

      c = new LinearConstraint(LinearConstraint.ConstraintRelation.LE);
      c.SetCoefficient(Y, Rational.MINUS_ONE);
      c.SetCoefficient(Z, Rational.ONE);
      c.rhs = Rational.FromInt(3);
      cs.Add(c);

      LinearConstraintSystem lcs = new LinearConstraintSystem(cs);
      Console.WriteLine("==================== The final linear constraint system ====================");
      lcs.Dump();
    }
    public LinearConstraintSystem/*!*/ Widen(LinearConstraintSystem/*!*/ lcs) {
      Contract.Requires(lcs != null);
      Contract.Ensures(Contract.Result<LinearConstraintSystem>() != null);
#endif
      if (this.IsBottom()) {
        return cce.NonNull(lcs.Clone());
      } else if (lcs.IsBottom()) {
        return cce.NonNull(this.Clone());
      } else if (this.IsTop() || lcs.IsTop()) {
        return new LinearConstraintSystem(new ArrayList /*LinearConstraint*/ ());
      }

      // create new LCS, we will add only verified constraints to this...
      ArrayList /*LinearConstraint*/ newConstraints = new ArrayList /*LinearConstraint*/ ();
      Contract.Assume(this.Constraints != null);
      foreach (LinearConstraint/*!*/ ccX in this.Constraints) {
        Contract.Assert(ccX != null);
        LinearConstraint cc = ccX;
#if DEBUG_PRINT
        Console.WriteLine("Widen checking: Starting to check constraint: {0}", cc);
#endif
        if (cc.IsConstant()) {
          // (Can this ever occur in the stable state of a LinearConstraintSystem?  --KRML)
          // constraint is unaffected by the frame components
#if DEBUG_PRINT
          Console.WriteLine("Widen checking:   --Adding it!");
#endif
          newConstraints.Add(cc);
          continue;
        }

        // PHASE I: verify constraints against all frame vertices...

        foreach (FrameElement/*!*/ vertex in cce.NonNull(lcs.FrameVertices)) {
          Contract.Assert(vertex != null);
          Rational lhs = cc.EvaluateLhs(vertex);
          if (lhs > cc.rhs) {
            // the vertex does not satisfy the inequality <=
            if (cc.Relation == LinearConstraint.ConstraintRelation.LE) {
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   throwing out because of vertex: {0}", vertex);
#endif
              goto CHECK_NEXT_CONSTRAINT;
            } else {
              // ... but it does satisfy the inequality >=
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   throwing out <= because of vertex: {0}", vertex);
#endif
              cc = cc.ChangeRelationToAtLeast();
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   left with constraint: {0}", cc);
#endif
            }
          } else if (cc.Relation == LinearConstraint.ConstraintRelation.EQ && lhs < cc.rhs) {
            // the vertex does not satisfy the inequality >=, and the constraint is an equality constraint
#if DEBUG_PRINT
            Console.WriteLine("Widen checking:   throwing out >= because of vertex: {0}", vertex);
#endif
            cc = cc.ChangeRelation(LinearConstraint.ConstraintRelation.LE);
#if DEBUG_PRINT
            Console.WriteLine("Widen checking:   left with contraint: {0}", cc);
#endif
          }
        }

        // PHASE II: verify constraints against all frame rays...

        foreach (FrameElement/*!*/ ray in cce.NonNull(lcs.FrameRays)) {
          Contract.Assert(ray != null);
          // The following assumes the constraint to have some dimension with a non-zero coefficient
          Rational lhs = cc.EvaluateLhs(ray);
          if (lhs.IsPositive) {
            // the ray does not satisfy the inequality <=
            if (cc.Relation == LinearConstraint.ConstraintRelation.LE) {
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   throwing out because of ray: {0}", ray);
#endif
              goto CHECK_NEXT_CONSTRAINT;
            } else {
              // ... but it does satisfy the inequality >=
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   throwing out <= because of ray: {0}", ray);
#endif
              cc = cc.ChangeRelationToAtLeast();
#if DEBUG_PRINT
              Console.WriteLine("Widen checking:   left with contraint: {0}", cc);
#endif
            }
          } else if (cc.Relation == LinearConstraint.ConstraintRelation.EQ && lhs.IsNegative) {
            // the ray does not satisfy the inequality >=, and the constraint is an equality constraint
#if DEBUG_PRINT
            Console.WriteLine("Widen checking:   throwing out >= because of ray: {0}", ray);
#endif
            cc = cc.ChangeRelation(LinearConstraint.ConstraintRelation.LE);
#if DEBUG_PRINT
            Console.WriteLine("Widen checking:   left with constraint: {0}", cc);
#endif
          }
        }

        // PHASE III: verify constraints against all frame lines...

        foreach (FrameElement/*!*/ line in cce.NonNull(lcs.FrameLines)) {
          Contract.Assert(line != null);
          // The following assumes the constraint to have some dimension with a non-zero coefficient
          Rational lhs = cc.EvaluateLhs(line);
          if (!lhs.IsZero) {
            // The line satisfies neither the inequality <= nor the equality ==
#if DEBUG_PRINT
            Console.WriteLine("Widen checking:   throwing out because of line: {0}", line);
#endif
            goto CHECK_NEXT_CONSTRAINT;
          }
        }

        // constraint has been verified, so add to new constraint system
#if DEBUG_PRINT
        Console.WriteLine("Widen checking:   --Adding it!");
#endif
        newConstraints.Add(cc);

      CHECK_NEXT_CONSTRAINT: {
        }
#if DEBUG_PRINT
        Console.WriteLine("Widen checking: done with that constraint");
#endif
      }

      return new LinearConstraintSystem(newConstraints);
    }
 /// <summary>
 /// Clones "list" and the elements of "list".
 /// </summary>
 /// <param name="list"></param>
 /// <returns></returns>
 ArrayList /*LinearConstraint*/ DeeperListCopy_LC(ArrayList/*!*/ /*LinearConstraint*/ list) {
   Contract.Requires(list != null);
   ArrayList /*LinearConstraint*/ z = new ArrayList /*LinearConstraint*/ (list.Count);
   foreach (LinearConstraint/*!*/ lc in list) {
     Contract.Assert(lc != null);
     z.Add(lc.Clone());
   }
   System.Diagnostics.Debug.Assert(z.Count == list.Count);
   return z;
 }