human
Complete this python program:
def io_toposort(inputs, outputs, orderings=None, clients=None):
assistant
#Here is the Python program you requested.

    """Perform topological sort from input and output nodes
    Parameters
    inputs : list or tuple of Variable instances
    outputs : list or tuple of Apply instances
    orderings : dict
    Key: Apply instance. Value: list of Apply instance.
    It is important that the value be a container with a deterministic
    iteration order. No sets allowed!
    clients : dict
    If a dict is provided it will be filled with mappings of
    node->clients for each node in the subgraph that is sorted
    """
    if ((not orderings) and (clients is None)):
        computed = set(inputs)
        todo = [o.owner for o in reversed(outputs) if o.owner]
        order = []
        while todo:
            cur = todo.pop()
            if (cur.outputs[0] in computed):
                continue
            if all([((i in computed) or (i.owner is None)) for i in cur.inputs]):
                computed.update(cur.outputs)
                order.append(cur)
            else:
                todo.append(cur)
                todo.extend((i.owner for i in cur.inputs if i.owner))
        return order
    compute_deps = None
    compute_deps_cache = None
    iset = set(inputs)
    deps_cache = {}
    if (not orderings):
        def compute_deps_cache(obj):
            if (obj in deps_cache):
                return deps_cache[obj]
            rval = []
            if (obj not in iset):
                if isinstance(obj, Variable):
                    if obj.owner:
                        rval = [obj.owner]
                elif isinstance(obj, Apply):
                    rval = list(obj.inputs)
                if rval:
                    if (not isinstance(rval, (list, OrderedSet))):
                        raise TypeError('Non-deterministic    collections    here    make    toposort    non-deterministic.')
                    deps_cache[obj] = list(rval)
                else:
                    deps_cache[obj] = rval
            else:
                deps_cache[obj] = rval
            return rval
    else:
        def compute_deps(obj):
            rval = []
            if (obj not in iset):
                if isinstance(obj, Variable):
                    if obj.owner:
                        rval = [obj.owner]
                elif isinstance(obj, Apply):
                    rval = list(obj.inputs)
                rval.extend(orderings.get(obj, []))
            else:
                assert (not orderings.get(obj, None))
            return rval
    topo = general_toposort(outputs, deps=compute_deps,...