public ITerm Substitute(string variable, ITerm expression) { if (variable == Variable) { // (λ x . t)[x := r] = λ x . t return this; } else { var free_variables = expression.GetFreeVariables(); if (free_variables.Contains(Variable)) { // Need to do an α-conversion. string t = Utilities.GetFreeVariable(Body.GetFreeVariables().Union(free_variables)); return new AbstractionTerm(t, Body.Substitute(Variable, new VariableTerm(t)).Substitute(variable, expression)); } else { // (λ y . t)[x := r] = λ y . (t[x := r]) return new AbstractionTerm(Variable, Body.Substitute(variable, expression)); } } }