<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def embed_bqm(source_bqm, embedding, target_adjacency, chain_strength=1.0, smear_vartype=None):
 """Embed a binary quadratic model onto a target graph. Args: source_bqm (:obj:`.BinaryQuadraticModel`):
 Binary quadratic model to embed. embedding (dict):
 where s is a source-model variable and t is a target-model variable. target_adjacency (dict/:class:`networkx.Graph`):
 where t is a variable in the target graph and Nt is its set of neighbours. chain_strength (float, optional):
 Magnitude of the quadratic bias (in SPIN-space) applied between variables to create chains. Note that the energy penalty of chain breaks is 2 * `chain_strength`. smear_vartype (:class:`.Vartype`, optional, default=None):
 When a single variable is embedded, it's linear bias is 'smeared' evenly over the chain. This parameter determines whether the variable is smeared in SPIN or BINARY space. By default the embedding is done according to the given source_bqm. Returns: :obj:`.BinaryQuadraticModel`: Target binary quadratic model. Examples: This example embeds a fully connected :math:`K_3` graph onto a square target graph. Embedding is accomplished by an edge contraction operation on the target graph: target-nodes 2 and 3 are chained to represent source-node c. True {(0, 1):
 1.0, (0, 3):
 1.0, (1, 2):
 1.0, (2, 3):
 -1.0} This example embeds a fully connected :math:`K_3` graph onto the target graph of a dimod reference structured sampler, `StructureComposite`, using the dimod reference `ExactSolver` sampler with a square graph specified. Target-nodes 2 and 3 are chained to represent source-node c. array([[-1, -1, -1, -1], [ 1, -1, -1, -1], [ 1, 1, -1, -1], [-1, 1, -1, -1], [-1, 1, 1, -1], """

    if smear_vartype is dimod.SPIN and source_bqm.vartype is dimod.BINARY:
        return embed_bqm(source_bqm.spin, embedding, target_adjacency,
                         chain_strength=chain_strength, smear_vartype=None).binary
    elif smear_vartype is dimod.BINARY and source_bqm.vartype is dimod.SPIN:
        return embed_bqm(source_bqm.binary, embedding, target_adjacency,
                         chain_strength=chain_strength, smear_vartype=None).spin

    # create a new empty binary quadratic model with the same class as source_bqm
    target_bqm = source_bqm.empty(source_bqm.vartype)

    # add the offset
    target_bqm.add_offset(source_bqm.offset)

    # start with the linear biases, spreading the source bias equally over the target variables in
    # the chain
    for v, bias in iteritems(source_bqm.linear):

        if v in embedding:
            chain = embedding[v]
        else:
            raise MissingChainError(v)

        if any(u not in target_adjacency for u in chain):
            raise InvalidNodeError(v, next(u not in target_adjacency for u in chain))

        b = bias / len(chain)

        target_bqm.add_variables_from({u: b for u in chain})

    # next up the quadratic biases, spread the quadratic biases evenly over the available
    # interactions
    for (u, v), bias in iteritems(source_bqm.quadratic):
        available_interactions = {(s, t) for s in embedding[u] for t in embedding[v] if s in target_adjacency[t]}

        if not available_interactions:
            raise MissingEdgeError(u, v)

        b = bias / len(available_interactions)

        target_bqm.add_interactions_from((u, v, b) for u, v in available_interactions)

    for chain in itervalues(embedding):

        # in the case where the chain has length 1, there are no chain quadratic biases, but we
        # none-the-less want the chain variables to appear in the target_bqm
        if len(chain) == 1:
            v, = chain
            target_bqm.add_variable(v, 0.0)
            continue

        quadratic_chain_biases = chain_to_quadratic(chain, target_adjacency, chain_strength)
        target_bqm.add_interactions_from(quadratic_chain_biases, vartype=dimod.SPIN)  # these are spin

        # add the energy for satisfied chains to the offset
        energy_diff = -sum(itervalues(quadratic_chain_biases))
        target_bqm.add_offset(energy_diff)

    return target_bqm