Example #1
0
 /// <summary>
 /// Adds to "lines" the lines implied by initial-variable columns not in basis
 /// (see section 3.4.2 of Cousot and Halbwachs), and adds to "constraints" the
 /// constraints to exclude those lines (see step 4.2 of section 3.4.3 of
 /// Cousot and Halbwachs).
 /// </summary>
 /// <param name="lines"></param>
 /// <param name="constraints"></param>
 public void ProduceLines(ArrayList /*FrameElement*//*!*/ lines, ArrayList /*LinearConstraint*//*!*/ constraints)
 {
     Contract.Requires(constraints != null);
     Contract.Requires(lines != null);
     // for every initial variable not in basis
     for (int i0 = 0; i0 < numInitialVars; i0++)
     {
         if (inBasis[i0] == -1)
         {
             FrameElement     fe = new FrameElement();
             LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ);
             for (int i = 0; i < numInitialVars; i++)
             {
                 if (i == i0)
                 {
                     fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), Rational.ONE);
                     lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), Rational.ONE);
                 }
                 else if (inBasis[i] != -1)
                 {
                     // i is a basis column
                     Contract.Assert(m[inBasis[i], i].HasValue(1));
                     Rational val = -m[inBasis[i], i0];
                     fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), val);
                     lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), val);
                 }
             }
             lines.Add(fe);
             constraints.Add(lc);
         }
     }
 }
Example #2
0
    /// <summary>
    /// Worker method of TraverseVertices.
    /// This method has no net effect on the tableau.
    /// </summary>
    /// <param name="basesSeenSoFar"></param>
    /// <param name="vertices"></param>
    /// <param name="rays"></param>
    void TraverseBases(ArrayList /*bool[]*//*!*/ basesSeenSoFar, ArrayList /*FrameElement*//*!*/ vertices, ArrayList /*FrameElement*//*!*/ rays) {
      Contract.Requires(rays != null);
      Contract.Requires(vertices != null);
      Contract.Requires(basesSeenSoFar != null);
      CheckInvariant();

      bool[] thisBasis = new bool[numSlackVars];
      for (int i = numInitialVars; i < rhsColumn; i++) {
        if (inBasis[i] != -1) {
          thisBasis[i - numInitialVars] = true;
        }
      }
      foreach (bool[]/*!*/ basis in basesSeenSoFar) {
        Contract.Assert(basis != null);
        Contract.Assert(basis.Length == numSlackVars);
        for (int i = 0; i < numSlackVars; i++) {
          if (basis[i] != thisBasis[i]) {
            goto COMPARE_WITH_NEXT_BASIS;
          }
        }
        // thisBasis and basis are the same--that is, basisColumns has been visited before--so
        // we don't traverse anything from here
        return;
      COMPARE_WITH_NEXT_BASIS: {
        }
      }
      // basisColumns has not been seen before; record thisBasis and continue with the traversal here
      basesSeenSoFar.Add(thisBasis);

#if DEBUG_PRINT
      Console.Write("TraverseBases, new basis:  ");
      foreach (bool t in thisBasis) {
        Console.Write("{0}", t ? "*" : ".");
      }
      Console.WriteLine();
      Dump();
#endif
      // Add vertex
      FrameElement v = new FrameElement();
      for (int i = 0; i < rows; i++) {
        int j = basisColumns[i];
        if (j < numInitialVars) {
          v.AddCoordinate((IVariable)cce.NonNull(dims[j]), m[i, rhsColumn]);
        }
      }
#if DEBUG_PRINT
      Console.WriteLine("  Adding vertex: {0}", v);
#endif
      vertices.Add(v);

      // Add rays.  Traverse all columns corresponding to slack variables that
      // are not in basis (see second bullet of section 3.4.2 of Cousot and Halbwachs).
      for (int i0 = numInitialVars; i0 < rhsColumn; i0++) {
        if (inBasis[i0] != -1) {
          // skip those slack-variable columns that are in basis
          continue;
        }
        // check if slack-variable, non-basis column i corresponds to an extreme ray
        for (int row = 0; row < rows; row++) {
          if (m[row, i0].IsPositive) {
            for (int k = numInitialVars; k < rhsColumn; k++) {
              if (inBasis[k] != -1 && m[row, k].IsNonZero) {
                // does not correspond to an extreme ray
                goto CHECK_NEXT_SLACK_VAR;
              }
            }
          }
        }
        // corresponds to an extreme ray
        FrameElement ray = new FrameElement();
        for (int i = 0; i < numInitialVars; i++) {
          int j0 = inBasis[i];
          Rational val = -m[j0, i0];
          ray.AddCoordinate((IVariable)cce.NonNull(dims[i]), val);
        }
#if DEBUG_PRINT
        Console.WriteLine("  Adding ray: {0}", ray);
#endif
        rays.Add(ray);
      CHECK_NEXT_SLACK_VAR: {
        }
      }

      // Continue traversal
      for (int i = numInitialVars; i < rhsColumn; i++) {
        int j = inBasis[i];
        if (j != -1) {
          // try moving i out of basis and some other slack-variable column into basis
          for (int k = numInitialVars; k < rhsColumn; k++) {
            if (inBasis[k] == -1 && m[j, k].IsPositive) {
              Rational[] undo = Pivot(j, k);
              // check if the new basis is feasible
              for (int p = 0; p < rows; p++) {
                int c = basisColumns[p];
                if (numInitialVars <= c && c < rhsColumn && m[p, rhsColumn].IsNegative) {
                  // not feasible
                  goto AFTER_TRAVERSE;
                }
              }
              TraverseBases(basesSeenSoFar, vertices, rays);
            AFTER_TRAVERSE:
              UnPivot(j, k, undo);
            }
          }
        }
      }
    }
Example #3
0
 /// <summary>
 /// Adds to "lines" the lines implied by initial-variable columns not in basis
 /// (see section 3.4.2 of Cousot and Halbwachs), and adds to "constraints" the
 /// constraints to exclude those lines (see step 4.2 of section 3.4.3 of
 /// Cousot and Halbwachs).
 /// </summary>
 /// <param name="lines"></param>
 /// <param name="constraints"></param>
 public void ProduceLines(ArrayList /*FrameElement*//*!*/ lines, ArrayList /*LinearConstraint*//*!*/ constraints) {
   Contract.Requires(constraints != null);
   Contract.Requires(lines != null);
   // for every initial variable not in basis
   for (int i0 = 0; i0 < numInitialVars; i0++) {
     if (inBasis[i0] == -1) {
       FrameElement fe = new FrameElement();
       LinearConstraint lc = new LinearConstraint(LinearConstraint.ConstraintRelation.EQ);
       for (int i = 0; i < numInitialVars; i++) {
         if (i == i0) {
           fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), Rational.ONE);
           lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), Rational.ONE);
         } else if (inBasis[i] != -1) {
           // i is a basis column
           Contract.Assert(m[inBasis[i], i].HasValue(1));
           Rational val = -m[inBasis[i], i0];
           fe.AddCoordinate((IVariable)cce.NonNull(dims[i]), val);
           lc.SetCoefficient((IVariable)cce.NonNull(dims[i]), val);
         }
       }
       lines.Add(fe);
       constraints.Add(lc);
     }
   }
 }
Example #4
0
        /// <summary>
        /// Worker method of TraverseVertices.
        /// This method has no net effect on the tableau.
        /// </summary>
        /// <param name="basesSeenSoFar"></param>
        /// <param name="vertices"></param>
        /// <param name="rays"></param>
        void TraverseBases(ArrayList /*bool[]*//*!*/ basesSeenSoFar, ArrayList /*FrameElement*//*!*/ vertices, ArrayList /*FrameElement*//*!*/ rays)
        {
            Contract.Requires(rays != null);
            Contract.Requires(vertices != null);
            Contract.Requires(basesSeenSoFar != null);
            CheckInvariant();

            bool[] thisBasis = new bool[numSlackVars];
            for (int i = numInitialVars; i < rhsColumn; i++)
            {
                if (inBasis[i] != -1)
                {
                    thisBasis[i - numInitialVars] = true;
                }
            }
            foreach (bool[] /*!*/ basis in basesSeenSoFar)
            {
                Contract.Assert(basis != null);
                Contract.Assert(basis.Length == numSlackVars);
                for (int i = 0; i < numSlackVars; i++)
                {
                    if (basis[i] != thisBasis[i])
                    {
                        goto COMPARE_WITH_NEXT_BASIS;
                    }
                }
                // thisBasis and basis are the same--that is, basisColumns has been visited before--so
                // we don't traverse anything from here
                return;

                COMPARE_WITH_NEXT_BASIS : {
                }
            }
            // basisColumns has not been seen before; record thisBasis and continue with the traversal here
            basesSeenSoFar.Add(thisBasis);

#if DEBUG_PRINT
            Console.Write("TraverseBases, new basis:  ");
            foreach (bool t in thisBasis)
            {
                Console.Write("{0}", t ? "*" : ".");
            }
            Console.WriteLine();
            Dump();
#endif
            // Add vertex
            FrameElement v = new FrameElement();
            for (int i = 0; i < rows; i++)
            {
                int j = basisColumns[i];
                if (j < numInitialVars)
                {
                    v.AddCoordinate((IVariable)cce.NonNull(dims[j]), m[i, rhsColumn]);
                }
            }
#if DEBUG_PRINT
            Console.WriteLine("  Adding vertex: {0}", v);
#endif
            vertices.Add(v);

            // Add rays.  Traverse all columns corresponding to slack variables that
            // are not in basis (see second bullet of section 3.4.2 of Cousot and Halbwachs).
            for (int i0 = numInitialVars; i0 < rhsColumn; i0++)
            {
                if (inBasis[i0] != -1)
                {
                    // skip those slack-variable columns that are in basis
                    continue;
                }
                // check if slack-variable, non-basis column i corresponds to an extreme ray
                for (int row = 0; row < rows; row++)
                {
                    if (m[row, i0].IsPositive)
                    {
                        for (int k = numInitialVars; k < rhsColumn; k++)
                        {
                            if (inBasis[k] != -1 && m[row, k].IsNonZero)
                            {
                                // does not correspond to an extreme ray
                                goto CHECK_NEXT_SLACK_VAR;
                            }
                        }
                    }
                }
                // corresponds to an extreme ray
                FrameElement ray = new FrameElement();
                for (int i = 0; i < numInitialVars; i++)
                {
                    int      j0  = inBasis[i];
                    Rational val = -m[j0, i0];
                    ray.AddCoordinate((IVariable)cce.NonNull(dims[i]), val);
                }
#if DEBUG_PRINT
                Console.WriteLine("  Adding ray: {0}", ray);
#endif
                rays.Add(ray);
                CHECK_NEXT_SLACK_VAR : {
                }
            }

            // Continue traversal
            for (int i = numInitialVars; i < rhsColumn; i++)
            {
                int j = inBasis[i];
                if (j != -1)
                {
                    // try moving i out of basis and some other slack-variable column into basis
                    for (int k = numInitialVars; k < rhsColumn; k++)
                    {
                        if (inBasis[k] == -1 && m[j, k].IsPositive)
                        {
                            Rational[] undo = Pivot(j, k);
                            // check if the new basis is feasible
                            for (int p = 0; p < rows; p++)
                            {
                                int c = basisColumns[p];
                                if (numInitialVars <= c && c < rhsColumn && m[p, rhsColumn].IsNegative)
                                {
                                    // not feasible
                                    goto AFTER_TRAVERSE;
                                }
                            }
                            TraverseBases(basesSeenSoFar, vertices, rays);
AFTER_TRAVERSE:
                            UnPivot(j, k, undo);
                        }
                    }
                }
            }
        }
    public LinearConstraintSystem/*!*/ Join(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*/ ());
      } else {
        LinearConstraintSystem/*!*/ z;
        // Start from the "larger" of the two frames (this is just a heuristic measure intended
        // to save work).
        Contract.Assume(this.FrameVertices != null);
        Contract.Assume(this.FrameRays != null);
        Contract.Assume(this.FrameLines != null);
        Contract.Assume(lcs.FrameVertices != null);
        Contract.Assume(lcs.FrameRays != null);
        Contract.Assume(lcs.FrameLines != null);
        if (this.FrameVertices.Count + this.FrameRays.Count + this.FrameLines.Count - this.FrameDimensions.Count <
          lcs.FrameVertices.Count + lcs.FrameRays.Count + lcs.FrameLines.Count - lcs.FrameDimensions.Count) {
          z = cce.NonNull(lcs.Clone());
          lcs = this;
        } else {
          z = cce.NonNull(this.Clone());
        }
#if DEBUG_PRINT
        Console.WriteLine("DEBUG: LinearConstraintSystem.Join ---------------");
        Console.WriteLine("z:");
        z.Dump();
        Console.WriteLine("lcs:");
        lcs.Dump();
#endif

        // Start by explicating the implicit lines of z for the dimensions dims(lcs)-dims(z).
        foreach (IVariable/*!*/ dim in lcs.FrameDimensions) {
          Contract.Assert(dim != null);
          if (!z.FrameDimensions.Contains(dim)) {
            z.FrameDimensions.Add(dim);
            FrameElement line = new FrameElement();
            line.AddCoordinate(dim, Rational.ONE);
            // Note:  AddLine is not called (because the line already exists in z--it's just that
            // it was represented implicitly).  Instead, just tack the explicit representation onto
            // FrameLines.
            Contract.Assume(z.FrameLines != null);
            z.FrameLines.Add(line);
#if DEBUG_PRINT
            Console.WriteLine("Join: After explicating line: {0}", line);
            z.Dump();
#endif
          }
        }

        // Now, the vertices, rays, and lines can be added.
        foreach (FrameElement/*!*/ v in lcs.FrameVertices) {
          Contract.Assert(v != null);
          z.AddVertex(v);
#if DEBUG_PRINT
          Console.WriteLine("Join: After adding vertex: {0}", v);
          z.Dump();
#endif
        }
        foreach (FrameElement/*!*/ r in lcs.FrameRays) {
          Contract.Assert(r != null);
          z.AddRay(r);
#if DEBUG_PRINT
          Console.WriteLine("Join: After adding ray: {0}", r);
          z.Dump();
#endif
        }
        foreach (FrameElement/*!*/ l in lcs.FrameLines) {
          Contract.Assert(l != null);
          z.AddLine(l);
#if DEBUG_PRINT
          Console.WriteLine("Join: After adding line: {0}", l);
          z.Dump();
#endif
        }
        // also add to z the implicit lines of lcs
        foreach (IVariable/*!*/ dim in z.FrameDimensions) {
          Contract.Assert(dim != null);
          if (!lcs.FrameDimensions.Contains(dim)) {
            // "dim" is a dimension that's explicit in "z" but implicit in "lcs"
            FrameElement line = new FrameElement();
            line.AddCoordinate(dim, Rational.ONE);
            z.AddLine(line);
#if DEBUG_PRINT
            Console.WriteLine("Join: After adding lcs's implicit line: {0}", line);
            z.Dump();
#endif
          }
        }

        z.SimplifyFrame();
        z.SimplifyConstraints();
        z.CheckInvariant();
#if DEBUG_PRINT
        Console.WriteLine("Join: Returning z:");
        z.Dump();
        Console.WriteLine("----------------------------------------");
#endif
        return z;
      }
    }
    public static void RunValidationC() {
      // Run the example in section 3.4.3 of Cousot and Halbwachs backwards, that is, from
      // from to constraints.
      IVariable/*!*/ dim1 = new TestVariable("X");
      IVariable/*!*/ dim2 = new TestVariable("Y");
      IVariable/*!*/ dim3 = new TestVariable("Z");
      Contract.Assert(dim1 != null);
      Contract.Assert(dim2 != null);
      Contract.Assert(dim3 != null);

      FrameElement s0 = new FrameElement();
      s0.AddCoordinate(dim1, Rational.ONE);
      s0.AddCoordinate(dim2, Rational.FromInts(1, 2));
      s0.AddCoordinate(dim3, Rational.FromInts(-1, 2));

      FrameElement s1 = new FrameElement();
      s1.AddCoordinate(dim1, Rational.ONE);
      s1.AddCoordinate(dim2, Rational.FromInts(-1, 2));
      s1.AddCoordinate(dim3, Rational.FromInts(1, 2));

      FrameElement s2 = new FrameElement();
      s2.AddCoordinate(dim1, Rational.FromInt(3));
      s2.AddCoordinate(dim2, Rational.FromInts(-3, 2));
      s2.AddCoordinate(dim3, Rational.FromInts(3, 2));

      FrameElement r0 = new FrameElement();
      r0.AddCoordinate(dim1, Rational.ONE);
      r0.AddCoordinate(dim2, Rational.FromInts(1, 2));
      r0.AddCoordinate(dim3, Rational.FromInts(-1, 2));

      FrameElement r1 = new FrameElement();
      r1.AddCoordinate(dim1, Rational.ONE);
      r1.AddCoordinate(dim2, Rational.ZERO);
      r1.AddCoordinate(dim3, Rational.ZERO);

      FrameElement d0 = new FrameElement();
      d0.AddCoordinate(dim1, Rational.ZERO);
      d0.AddCoordinate(dim2, Rational.ONE);
      d0.AddCoordinate(dim3, Rational.ONE);

      LinearConstraintSystem lcs = new LinearConstraintSystem(s0);
      lcs.Dump();

      lcs.AddVertex(s1);
      lcs.Dump();

      lcs.AddVertex(s2);
      lcs.Dump();

      lcs.AddRay(r0);
      lcs.Dump();

      lcs.AddRay(r1);
      lcs.Dump();

      lcs.AddLine(d0);
      lcs.Dump();

      lcs.SimplifyConstraints();
      lcs.Dump();

#if LATER
      lcs.GenerateFrameFromConstraints(); // should give us back the original frame...
#endif
    }
    public static void RunValidationA() {
      IVariable/*!*/ dim1 = new TestVariable("X");
      IVariable/*!*/ dim2 = new TestVariable("Y");
      IVariable/*!*/ dim3 = new TestVariable("Z");
      Contract.Assert(dim1 != null);
      Contract.Assert(dim2 != null);
      Contract.Assert(dim3 != null);

      FrameElement s1 = new FrameElement();
      s1.AddCoordinate(dim1, Rational.ONE);
      s1.AddCoordinate(dim2, Rational.MINUS_ONE);
      s1.AddCoordinate(dim3, Rational.ZERO);
      FrameElement s2 = new FrameElement();
      s2.AddCoordinate(dim1, Rational.MINUS_ONE);
      s2.AddCoordinate(dim2, Rational.ONE);
      s2.AddCoordinate(dim3, Rational.ZERO);
      FrameElement r1 = new FrameElement();
      r1.AddCoordinate(dim1, Rational.ZERO);
      r1.AddCoordinate(dim2, Rational.ZERO);
      r1.AddCoordinate(dim3, Rational.ONE);
      FrameElement d1 = new FrameElement();
      d1.AddCoordinate(dim1, Rational.ONE);
      d1.AddCoordinate(dim2, Rational.ONE);
      d1.AddCoordinate(dim3, Rational.ZERO);

      // create lcs from frame -- cf. Cousot/Halbwachs 1978, section 3.3.1.1
      LinearConstraintSystem lcs = new LinearConstraintSystem(s1);
      lcs.Dump();

      lcs.AddVertex(s2);
      lcs.Dump();

      lcs.AddRay(r1);
      lcs.Dump();

      lcs.AddLine(d1);
      lcs.Dump();

      lcs.SimplifyConstraints();
      lcs.Dump();

#if LATER
      lcs.GenerateFrameFromConstraints(); // should give us back the original frame...
#endif
      Console.WriteLine("IsSubset? {0}", lcs.IsSubset(lcs.Clone()));
      lcs.Dump();
    }