/// <summary>
    /// Return a new expression in which each variable has been 
    /// replaced by an expression representing what is known about
    /// that variable.
    /// </summary>
    private IExpr/*!*/ InlineVariables(Elt/*!*/ element, IExpr/*!*/ expr, ISet/*<IVariable!>*//*!*/ notInlineable,
        OnUnableToInline/*!*/ unableToInline) {
      Contract.Requires(unableToInline != null);
      Contract.Requires(notInlineable != null);
      Contract.Requires(expr != null);
      Contract.Requires(element != null);
      Contract.Ensures(Contract.Result<IExpr>() != null);
      IVariable var = expr as IVariable;
      if (var != null) {
        /*MicroLattice*/
        Element value = element[var];
        if (notInlineable.Contains(var) || value == null || this.microLattice.IsTop(value)) {
          return unableToInline(var); // We don't know anything about this variable.
        } else {
          // GetFoldExpr returns null when it can yield an expression that
          // can be substituted for the variable.
          IExpr valueExpr = this.microLattice.GetFoldExpr(value);
          return (valueExpr == null) ? var : valueExpr;
        }
      }

      // else

      IFunApp fun = expr as IFunApp;
      if (fun != null) {
        IList newargs = new ArrayList();
        foreach (IExpr/*!*/ arg in fun.Arguments) {
          Contract.Assert(arg != null);
          newargs.Add(InlineVariables(element, arg, notInlineable, unableToInline));
        }
        return fun.CloneWithArguments(newargs);
      }

      // else

      IFunction lambda = expr as IFunction;
      if (lambda != null) {
        IMutableSet x = new HashSet(1);
        x.Add(lambda.Param);

        // Don't inline the bound variable
        return lambda.CloneWithBody(
                   InlineVariables(element, lambda.Body,
                                    cce.NonNull(Set.Union(notInlineable, x)), unableToInline)
               );
      }

      // else

      if (expr is IUnknown) {
        return expr;
      } else {
        throw
          new System.NotImplementedException("cannot inline identifies in expression " + expr);
      }
    }
Example #2
0
        /// <summary>
        /// Return a new expression in which each variable has been
        /// replaced by an expression representing what is known about
        /// that variable.
        /// </summary>
        private IExpr /*!*/ InlineVariables(Elt /*!*/ element, IExpr /*!*/ expr, ISet /*<IVariable!>*//*!*/ notInlineable,
                                            OnUnableToInline /*!*/ unableToInline)
        {
            Contract.Requires(unableToInline != null);
            Contract.Requires(notInlineable != null);
            Contract.Requires(expr != null);
            Contract.Requires(element != null);
            Contract.Ensures(Contract.Result <IExpr>() != null);
            IVariable var = expr as IVariable;

            if (var != null)
            {
                /*MicroLattice*/
                Element value = element[var];
                if (notInlineable.Contains(var) || value == null || this.microLattice.IsTop(value))
                {
                    return(unableToInline(var)); // We don't know anything about this variable.
                }
                else
                {
                    // GetFoldExpr returns null when it can yield an expression that
                    // can be substituted for the variable.
                    IExpr valueExpr = this.microLattice.GetFoldExpr(value);
                    return((valueExpr == null) ? var : valueExpr);
                }
            }

            // else

            IFunApp fun = expr as IFunApp;

            if (fun != null)
            {
                IList newargs = new ArrayList();
                foreach (IExpr /*!*/ arg in fun.Arguments)
                {
                    Contract.Assert(arg != null);
                    newargs.Add(InlineVariables(element, arg, notInlineable, unableToInline));
                }
                return(fun.CloneWithArguments(newargs));
            }

            // else

            IFunction lambda = expr as IFunction;

            if (lambda != null)
            {
                IMutableSet x = new HashSet(1);
                x.Add(lambda.Param);

                // Don't inline the bound variable
                return(lambda.CloneWithBody(
                           InlineVariables(element, lambda.Body,
                                           cce.NonNull(Set.Union(notInlineable, x)), unableToInline)
                           ));
            }

            // else

            if (expr is IUnknown)
            {
                return(expr);
            }
            else
            {
                throw
                    new System.NotImplementedException("cannot inline identifies in expression " + expr);
            }
        }