public static bool ContainsBoundSymbol(Expression expression, SymbolRef symbol) { if (expression is BoundSymbolExpression) { var boundSymbol = (BoundSymbolExpression)expression; if (boundSymbol.Symbol == symbol) return true; else return false; } else if (expression is AbstractionExpression) { var abstraction = (AbstractionExpression)expression; if (abstraction.Left != symbol) return ContainsBoundSymbol(abstraction.Right, symbol); else return false; } else if (expression is ApplicationExpression) { var application = (ApplicationExpression)expression; if (ContainsBoundSymbol(application.Left, symbol)) return true; return ContainsBoundSymbol(application.Right, symbol); } else if (expression is BuiltinExpression) { var builtin = (BuiltinExpression)expression; if (ContainsBoundSymbol(builtin.Left, symbol)) return true; return ContainsBoundSymbol(builtin.Right, symbol); } else { return false; } }
public static Expression Substitute(Expression expression, SymbolRef symbol, Expression replacement) { if (expression is BoundSymbolExpression) { var boundSymbol = (BoundSymbolExpression)expression; if (boundSymbol.Symbol == symbol) return replacement; else return expression; } else if (expression is AbstractionExpression) { var abstraction = (AbstractionExpression)expression; if (abstraction.Left != symbol) return new AbstractionExpression { Left = abstraction.Left, Right = Substitute(abstraction.Right, symbol, replacement) }; else return expression; } else if (expression is ApplicationExpression) { var application = (ApplicationExpression)expression; return new ApplicationExpression { Left = Substitute(application.Left, symbol, replacement), Right = Substitute(application.Right, symbol, replacement) }; } else if (expression is BuiltinExpression) { var builtin = (BuiltinExpression)expression; return new BuiltinExpression { Left = Substitute(builtin.Left, symbol, replacement), Right = Substitute(builtin.Right, symbol, replacement), Display = builtin.Display, Evaluate = builtin.Evaluate }; } else { return expression; } }