'Initialize a Routine instance.
Parameters
name : string
Name of the routine.
arguments : list of Arguments
These are things that appear in arguments of a routine, often
appearing on the right-hand side of a function call.  These are
commonly InputArguments but in some languages, they can also be
OutputArguments or InOutArguments (e.g., pass-by-reference in C
code).
results : list of Results
These are the return values of the routine, often appearing on
the left-hand side of a function call.  The difference between
Results and OutputArguments and when you should use each is
language-specific.
local_vars : list of Symbols
These are used internally by the routine.
global_vars : list of Symbols
Variables which will not be passed into the function.'

def __init__(self, name, arguments, results, local_vars, global_vars):

    input_symbols = set([])
    symbols = set([])
    for arg in arguments:
        if isinstance(arg, OutputArgument):
            symbols.update(arg.expr.free_symbols)
        elif isinstance(arg, InputArgument):
            input_symbols.add(arg.name)
        elif isinstance(arg, InOutArgument):
            input_symbols.add(arg.name)
            symbols.update(arg.expr.free_symbols)
        else:
            raise ValueError(('Unknown    Routine    argument:    %s' % arg))
    for r in results:
        if (not isinstance(r, Result)):
            raise ValueError(('Unknown    Routine    result:    %s' % r))
        symbols.update(r.expr.free_symbols)
    symbols = set([(s.label if isinstance(s, Idx) else s) for s in symbols])
    notcovered = symbols.difference(input_symbols.union(local_vars).union(global_vars))
    if (notcovered != set([])):
        raise ValueError(('Symbols    needed    for    output    are    not    in    input    ' + ',    '.join([str(x) for x in notcovered])))
    self.name = name
    self.arguments = arguments
    self.results = results
    self.local_vars = local_vars
    self.global_vars = global_vars
