コード例 #1
0
    public override Element/*!*/ NontrivialJoin(Element/*!*/ first, Element/*!*/ second) {
      //Contract.Requires(second != null);
      //Contract.Requires(first != null);
      Contract.Ensures(Contract.Result<Element>() != null);
      Elt a = (Elt)first;
      Elt b = (Elt)second;
      Contract.Assert(a.what != What.Bottom && b.what != What.Bottom);
      if (a.what == What.Exact && b.what == What.Exact) {
        Contract.Assert(a.ty != null && b.ty != null);
        if (factory.IsTypeEqual(a.ty, b.ty)) {
          return a;
        } else {
          return new Elt(What.Bounds, factory.JoinTypes(a.ty, b.ty));
        }
      }

      // The result is going to be a Bounds, since at least one of the operands is a Bounds.
      Contract.Assert(1 <= a.BoundsCount && 1 <= b.BoundsCount);  // a preconditions is that neither operand is Top
      int n = a.BoundsCount + b.BoundsCount;

      // Special case:  a and b each has exactly one bound
      if (n == 2) {
        Contract.Assert(a.ty != null && b.ty != null);
        IExpr join = factory.JoinTypes(a.ty, b.ty);
        Contract.Assert(join != null);
        if (join == a.ty && a.what == What.Bounds) {
          return a;
        } else if (join == b.ty && b.what == What.Bounds) {
          return b;
        } else {
          return new Elt(What.Bounds, join);
        }
      }

      // General case
      ArrayList /*IExpr*/ allBounds = new ArrayList /*IExpr*/ (n);  // final size
      ArrayList /*IExpr!*/ result = new ArrayList /*IExpr!*/ (n);  // a guess at the size, but could be as big as size(a)*size(b)
      if (a.ty != null) {
        allBounds.Add(a.ty);
      } else {
        allBounds.AddRange(cce.NonNull(a.manyBounds));
      }
      int bStart = allBounds.Count;
      if (b.ty != null) {
        allBounds.Add(b.ty);
      } else {
        allBounds.AddRange(cce.NonNull(b.manyBounds));
      }
      // compute the join of each pair, putting non-redundant joins into "result"
      for (int i = 0; i < bStart; i++) {
        IExpr/*!*/ aBound = cce.NonNull((IExpr/*!*/)allBounds[i]);
        for (int j = bStart; j < allBounds.Count; j++) {
          IExpr/*!*/ bBound = (IExpr/*!*/)cce.NonNull(allBounds[j]);

          IExpr/*!*/ join = factory.JoinTypes(aBound, bBound);
          Contract.Assert(join != null);

          int k = 0;
          while (k < result.Count) {
            IExpr/*!*/ r = (IExpr/*!*/)cce.NonNull(result[k]);
            if (factory.IsSubType(join, r)) {
              // "join" is more restrictive than a bound already placed in "result",
              // so toss out "join" and compute the join of the next pair
              goto NEXT_PAIR;
            } else if (factory.IsSubType(r, join)) {
              // "join" is less restrictive than a bound already placed in "result",
              // so toss out that old bound
              result.RemoveAt(k);
            } else {
              k++;
            }
          }
          result.Add(join);
        NEXT_PAIR: {
          }
        }
      }
      return new Elt(result, result.Count);
    }
コード例 #2
0
        public override Element /*!*/ NontrivialJoin(Element /*!*/ first, Element /*!*/ second)
        {
            //Contract.Requires(second != null);
            //Contract.Requires(first != null);
            Contract.Ensures(Contract.Result <Element>() != null);
            Elt a = (Elt)first;
            Elt b = (Elt)second;

            Contract.Assert(a.what != What.Bottom && b.what != What.Bottom);
            if (a.what == What.Exact && b.what == What.Exact)
            {
                Contract.Assert(a.ty != null && b.ty != null);
                if (factory.IsTypeEqual(a.ty, b.ty))
                {
                    return(a);
                }
                else
                {
                    return(new Elt(What.Bounds, factory.JoinTypes(a.ty, b.ty)));
                }
            }

            // The result is going to be a Bounds, since at least one of the operands is a Bounds.
            Contract.Assert(1 <= a.BoundsCount && 1 <= b.BoundsCount); // a preconditions is that neither operand is Top
            int n = a.BoundsCount + b.BoundsCount;

            // Special case:  a and b each has exactly one bound
            if (n == 2)
            {
                Contract.Assert(a.ty != null && b.ty != null);
                IExpr join = factory.JoinTypes(a.ty, b.ty);
                Contract.Assert(join != null);
                if (join == a.ty && a.what == What.Bounds)
                {
                    return(a);
                }
                else if (join == b.ty && b.what == What.Bounds)
                {
                    return(b);
                }
                else
                {
                    return(new Elt(What.Bounds, join));
                }
            }

            // General case
            ArrayList /*IExpr*/  allBounds = new ArrayList/*IExpr*/ (n);  // final size
            ArrayList /*IExpr!*/ result    = new ArrayList/*IExpr!*/ (n); // a guess at the size, but could be as big as size(a)*size(b)

            if (a.ty != null)
            {
                allBounds.Add(a.ty);
            }
            else
            {
                allBounds.AddRange(cce.NonNull(a.manyBounds));
            }
            int bStart = allBounds.Count;

            if (b.ty != null)
            {
                allBounds.Add(b.ty);
            }
            else
            {
                allBounds.AddRange(cce.NonNull(b.manyBounds));
            }
            // compute the join of each pair, putting non-redundant joins into "result"
            for (int i = 0; i < bStart; i++)
            {
                IExpr /*!*/ aBound = cce.NonNull((IExpr /*!*/)allBounds[i]);
                for (int j = bStart; j < allBounds.Count; j++)
                {
                    IExpr /*!*/ bBound = (IExpr /*!*/)cce.NonNull(allBounds[j]);

                    IExpr /*!*/ join = factory.JoinTypes(aBound, bBound);
                    Contract.Assert(join != null);

                    int k = 0;
                    while (k < result.Count)
                    {
                        IExpr /*!*/ r = (IExpr /*!*/)cce.NonNull(result[k]);
                        if (factory.IsSubType(join, r))
                        {
                            // "join" is more restrictive than a bound already placed in "result",
                            // so toss out "join" and compute the join of the next pair
                            goto NEXT_PAIR;
                        }
                        else if (factory.IsSubType(r, join))
                        {
                            // "join" is less restrictive than a bound already placed in "result",
                            // so toss out that old bound
                            result.RemoveAt(k);
                        }
                        else
                        {
                            k++;
                        }
                    }
                    result.Add(join);
                    NEXT_PAIR : {
                    }
                }
            }
            return(new Elt(result, result.Count));
        }