def define_sub_model(dsp, inputs, outputs, models):
    """
    Defines a sub-model from a dsp.

    :param dsp:
        Original model.
    :type dsp: schedula.Dispatcher

    :param inputs:
        Data inputs.
    :type inputs: list | tuple

    :param outputs:
        Data outputs.
    :type outputs: list | tuple

    :param models:
        Data models.
    :type models: list | tuple

    :return:
        A sub-model.
    :rtype: schedula.Dispatcher
    """
    assert not set(models).difference(dsp.nodes), models
    sub = dsp.shrink_dsp(set(inputs or []).union(models), outputs)
    assert set(sub.nodes).issuperset(set(inputs).union(outputs)), models
    return sub
