def with_weighted_lookup(old_fn, lookup, freq):
    """
    Wrap a similarity function, looking up all preds for the given lemmas,
    weightings the pairwise similarities by frequency,
    and returning 0 if the lemma was not found
    :param old_fn: function taking two indices and returning a similarity score
    :param lookup: mapping from lemmas to sets of indices
    :param freq: mapping from indices to frequencies
    :return: similarity function
    """
    def sim_fn(a, b, *args, **kwargs):
        "Calculate the average similarity across all preds, weighted by frequency"
        scores = []
        freqs = []
        try:
            for p in lookup[a]:
                for q in lookup[b]:
                    # Get similarity and frequency
                    scores.append(old_fn(p, q, *args, **kwargs))
                    freqs.append(freq[p]*freq[q])
            # Calculate weighted average
            totalscore = sum(scores[i] * freqs[i] for i in range(len(scores)))
            totalfreq = sum(freqs)
            return totalscore / totalfreq
        except KeyError:
            # Unknown lemmas
            return 0
    return sim_fn