#!/usr/bin/python
# -*- coding: UTF-8 -*-

"""
visitors.py

@author ejnp
"""

import ast
import lambda_calculus_ast


class FreeVariables(ast.NodeVisitor):
    """Visits each node of a lambda calculus abstract syntax tree and
    determines which variables (if any) are unbound. Ultimately provides a set
    of string variable names.
    """

    def visit_Variable(self, node):
        """FV(x) = {x}"""
        return {node.name}

    def visit_Application(self, node):
        """FV((e1 e2)) = FV(e1) U FV(e2)"""
        return (self.visit(node.left_expression) |
                self.visit(node.right_expression))

    def visit_Abstraction(self, node):
        """FV(λx.e) = FV(e) - {x}"""
        return self.visit(node.expression) - self.visit(node.parameter)

@@ -761,8 +761,1250 @@
 ameter)%0A
+%0Aclass AlphaConversion(ast.NodeVisitor):%0A    %22%22%22Nondestructively substitutes all occurances of a particular variable%0A    for an arbitrary expression.%0A%0A    Attributes:%0A        to_return (Variable): Instance whose name attribute must match the%0A            variable that's being replaced%0A        replacement (Expression): Object inserted into the visited AST%0A    %22%22%22%0A%0A    def __init__(self, to_replace, replacement):%0A        self.to_replace = to_replace%0A        self.replacement = replacement%0A%0A    def visit_Variable(self, node):%0A        %22%22%22If the appropriate variable name is found, replace it.%22%22%22%0A        if node.name == self.to_replace.name:%0A            return self.replacement%0A        else:%0A            return Variable(node.name)%0A%0A    def visit_Application(self, node):%0A        %22%22%22Returns a new Application after visiting both application%0A        expressions.%0A        %22%22%22%0A        return Application(self.visit(node.left_expression),%0A                           self.visit(node.right_expression))%0A%0A    def visit_Abstraction(self, node):%0A        %22%22%22Returns a new Abstraction after visiting both the parameter and%0A        body.%0A        %22%22%22%0A        return Abstraction(self.visit(node.parameter),%0A                           self.visit(node.body))%0A

Implement alpha conversion functionality