<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def canon_ref(did: str, ref: str, delimiter: str = None):
 """ Given a reference in a DID document, return it in its canonical form of a URI. :param did: DID acting as the identifier of the DID document :param ref: reference to canonicalize, either a DID or a fragment pointing to a location in the DID doc :param delimiter: delimiter character marking fragment (default '#') or introducing identifier (';') against DID resource """


    if not ok_did(did):
        raise BadIdentifier('Bad DID {} cannot act as DID document identifier'.format(did))

    if ok_did(ref):  # e.g., LjgpST2rjsoxYegQDRm7EL
        return 'did:sov:{}'.format(did)

    if ok_did(resource(ref, delimiter)):  # e.g., LjgpST2rjsoxYegQDRm7EL#keys-1
        return 'did:sov:{}'.format(ref)

    if ref.startswith('did:sov:'):  # e.g., did:sov:LjgpST2rjsoxYegQDRm7EL, did:sov:LjgpST2rjsoxYegQDRm7EL#3
        rv = ref[8:]
        if ok_did(resource(rv, delimiter)):
            return ref
        raise BadIdentifier('Bad URI {} does not correspond to a sovrin DID'.format(ref))

    if urlparse(ref).scheme:  # e.g., https://example.com/messages/8377464
        return ref

    return 'did:sov:{}{}{}'.format(did, delimiter if delimiter else '#', ref)