<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def proof_req_pred_referents(proof_req: dict) -> dict: """ Given a proof request with all requested predicates having cred def id restrictions, return its predicate referents by cred def id and attribute, mapping a predicate and a limit. The returned structure can be useful in downstream processing to filter cred-infos for predicates. :param proof_req: proof request with all requested predicate specifications having cred def id restriction; e.g., :: { 'name': 'proof_req', 'version': '0.0', 'requested_attributes': { } 'requested_predicates': { '194_highscore_GE_uuid': { 'name': 'highscore', 'p_type': '>=', 'p_value': '100000', 'restrictions': [ { 'cred_def_id': 'WgWxqztrNooG92RXvxSTWv:3:CL:194:tag' } ], 'non_revoked': { } }, '194_level_GE_uuid': { 'name': 'level', 'p_type': '>=', 'p_value': '10', 'restrictions': [ { 'cred_def_id': 'WgWxqztrNooG92RXvxSTWv:3:CL:194:tag' } ], 'non_revoked': { } }, '194_attempts_LE_uuid': { 'name': 'attempts', 'p_type': '<=', 'p_value': '3', 'restrictions': [ { 'cred_def_id': 'WgWxqztrNooG92RXvxSTWv:3:CL:194:tag' } ], 'non_revoked': { } }, '198_employees_LT_uuid': { 'name': 'employees', 'p_type': '<', 'p_value': '100', 'restrictions': [ { 'cred_def_id': 'WgWxqztrNooG92RXvxSTWv:3:CL:198:tag' } ], 'non_revoked': { } }, '198_employees_GE_uuid': { 'name': 'employees', 'p_type': '>=', 'p_value': '50', 'restrictions': [ { 'cred_def_id': 'WgWxqztrNooG92RXvxSTWv:3:CL:198:tag' } ], 'non_revoked': { } }, } } :return: nested dict mapping cred def id to name to proof request referent to predicate and limit; e.g., :: { 'WgWxqztrNooG92RXvxSTWv:3:CL:194:tag': { 'highscore': { '194_level_GE_uuid': ['>=', 100000] }, 'level': { '194_level_GE_uuid': ['>=', 10] }, 'attempts': { '194_attempts_LE_uuid': ['<=', 3] } }, 'WgWxqztrNooG92RXvxSTWv:3:CL:198:tag': { 'employees': { # may have many preds per attr, but always 1 uuid and 1 relation per pred '198_LT_employees_uuid': ['<=', 100] '198_GE_employees_uuid': ['>=', 50] } } } """


    rv = {}
    for uuid, spec in proof_req['requested_predicates'].items():
        cd_id = None
        for restriction in spec.get('restrictions', []):
            cd_id = restriction.get('cred_def_id', None)
            if cd_id:
                break
        if not cd_id:
            continue
        if cd_id not in rv:  # cd_id of None is not OK
            rv[cd_id] = {}
        if spec['name'] not in rv[cd_id]:
            rv[cd_id][spec['name']] = {}
        rv[cd_id][spec['name']][uuid] = [spec['p_type'], Predicate.to_int(spec['p_value'])]

    return rv