Example #1
0
        /// <summary>
        ///  Yield an expression that is 'inexpr' with 'var' replaced by 'subst'.
        /// </summary>
        /// <param name="subst">The expression to substitute.</param>
        /// <param name="var">The variable to substitute for.</param>
        /// <param name="inexpr">The expression to substitute into.</param>
        public static IExpr /*!*/ Substitute(IExpr /*!*/ subst, IVariable /*!*/ var, IExpr /*!*/ inexpr)
        {
            Contract.Requires(inexpr != null);
            Contract.Requires(var != null);
            Contract.Requires(subst != null);
            Contract.Ensures(Contract.Result <IExpr>() != null);
            IExpr result = null;

            if (inexpr is IVariable)
            {
                result = inexpr.Equals(var) ? subst : inexpr;
            }
            else if (inexpr is IFunApp)
            {
                IFunApp /*!*/ funapp  = (IFunApp /*!*/)cce.NonNull(inexpr);
                IList         newargs = null;

                var x = new System.Collections.Generic.List <IExpr>();
                foreach (IExpr arg in funapp.Arguments)
                {
                    x.Add(Substitute(subst, var, arg));
                }
                newargs = new ArrayList(x);
                //newargs = new ArrayList{ IExpr/*!*/ arg in funapp.Arguments; Substitute(subst, var, arg) };
                result = funapp.CloneWithArguments(newargs);
            }
            else if (inexpr is IFunction)
            {
                IFunction /*!*/ fun = (IFunction /*!*/)cce.NonNull(inexpr);

                if (fun.Param.Equals(var))
                {
                    result = fun;
                }
                else
                {
                    result = fun.CloneWithBody(Substitute(subst, var, fun.Body));
                }
            }
            else if (inexpr is IUnknown)
            {
                result = inexpr;
            }
            else
            {
                { Contract.Assert(false); throw new cce.UnreachableException(); }
            }

            return(result);
        }
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);
            }
        }