/// <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); } }
/// <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); } }